promise的作用
参考:https://www.imooc.com/learn/949
它是一个 代理对象,它和原生要进行的操作并没有关系,它引入一个回调,避免了多个回调。
-用于异步计算
-将异步操作队列化,按照预期顺序执行,返回符合预期的结果
-可以在对象之间传递promise,帮助我们处理队列
1.promise说明
new Promise(
//它是一个执行器
function(resolve, reject){
//将要耗时的异步操作放在此函数中执行
resolve(); //成功调用此函数,表示数据处理完成
reject(); //数据处理出错,调用reject
}
).then(function A(){
//如果调用了resolve(),则调用第一个方法A()
}, function B(){
//如果调用了 reject(),则调用B()
});
2.promise有三个状态
pending 初始化状态
fulfilled 操作成功
rejected 操作失败
当状态发生改变,就会触发 .then()里的响应函数处理后面的事情。
promise状态一经改变,不会再变。
3.promise的then()
promise执行每个then()时,都会返回一个新的promise实例
当执行完一个then()后,会从队列出取出下一个继续执行。
-状态响应函数可以返回新的promise或其它值
-如果返回新的promise,那么下一级 then()会在新的promise状态改变之后执行
-如果返回其他任何值,则会立即执行下一级then()
4.如果在then()中不返回promise会怎么样
如果在then()中不返回promise或者不返回任何东西,则默认执行下一个then()
5.错误处理
promise在执行器中执行时,如果捕获到异常,会将promise标记为
rejected状态,并交给rejected()函数进行处理,也会寻找catch进行处理。
推荐在所有then()的后面通过catch来捕获所有异常处理错误的方法。
6.在catch 后调用then()会怎么样
catch也会返回promise实例,如果catch执行完没有rejected,后面如果有then(),会继续执行完。如果catch执行完有异常出现,则会跳过后面的then,如果在catch后面还有catch,则还会执行catch后面的catch。
7.promise的函数
promise.all([p1,p2,....])接受一个数组作为参数,会返回一个新的promise实例。
数组可以是promise或其他值,promise会等待执行完成,当所有promise都完成,返回值是全部值的数组。
有任何一个失败,该promise失败,返回值是第一个失败的子promise的值。
8.promise.resolve()
作用:返回一个fulfilled的promise实例或原始的promise
分为以下几种情况
-参数为空时,返回一个状态为fulfilled的promise实例
-参数是一个跟promise无关的值,返回一个状态为fulfilled的promise实例,同时promise函数会得到这个参数
-参数为promise实例,则返回该实例,不作任何修改
-参数为thenable,则会立刻执行它的then()函数
9.promise.reject()
返回一个rejected的promise实例
-promise.reject()不认thenable
-其他与resolve()类似
10.promise.race()
与promise.all()类似
不同在于它有任意一个完成就算完成,不等待所有都完成。
常见用法:
把异步操作和定时器放在一起,如果定时器先触发,则知道超时,提示用户。
11.开发中的用法
将异步包装成promise
所有返回结果生成队列,用于其他地方
12.开发实战举例
说明:
1.有一个表单,表单中有多个附件,提交表单前需要将所有的附件上传,并将所有附件上传返回的id随表单一块提交。
2.附件上传到服务器只能一次上传一个。
这就需要保证所有的附件上传完,并将所有的结果返回后,再提交表单。
思路:
可以为每一个附件上传构建成一个Promise,并使用promise.all()来执行这N个Promise,这样就保证了所有的附件上传都返回了结果。
-如果所有附件上传成功了,下一步可以提交表单。
-如果promise.all()返回的结果有上传附件失败的情况,可以提示用户有某个附件未上传成功,是否继续提交表单。
let promises=[]; //存放所有的附件上传promise
//fileList为保存附件的数组,根据附件文件数,创建多个promise
this.fileList.forEach(item=>{
this.formData = new FormData();
this.formData.append('file', item);
let p = new Promise(resolve => {
this.$http({ //自己实现的上传附件到服务器的方法
showModal: true,
url: 'xxxxxxxx',
method: 'post',
data: this.formData,
headers: {
'Content-Type': 'multipart/form-data',
'X-Requested-With': 'XMLHttpRequest',
},
}).then(res=>{
resolve(res); //将结果传递,不调用,后面执行Promise.all拿不到结果
})
})
promises.push(p); //将所有的promise存在数组中
})
Promise.all(promises).then(results=>{
results.forEach(res=>{
if(res.code==='200'){
//处理多个promise执行后返回的结果
//记录上传附件返回的,需要表单提交的信息
}
})
if(所有附件上传成功){
//提交表单
}else{
//提示用户有附件上传失败,是否继承提交表单
}
})