1.promise的用途
Promise是一种异步编程模式,用来解决js异步编程的回调问题:
- 规范回调的名字或顺序
- 拒绝回调地狱,让代码可读性更强
- 很方便的捕获错误
Promise实例有三种状态:
- pending(待定)
- fulfilled(已执行)
- rejected(已拒绝)
Promise特点:
- promise对象的状态不受外界影响,而且状态一旦改变就不会再变
- 在new promise中执行resolve()时,状态由pennding变成fulfilled,执行reject()时, 状态会由pending变成rejected.
- new promise参数中的函数会立即执行,等同于同步代码
- 当promise状态改变就会触发then()中的回调函数,这个回调函数属于microTask, 优先级高于macroTask但低于同步代码
2.如何创建new Promise
let p=(method,url,options)=>{
return new Promise((resove,reject)=>{
... //一段异步代码 pending状态
if(succeed){ //fulfilled状态
resolve();
}else{ //rejected 状态
reject();
}
})
}
p.then(sucess,fail).then(...)
- return new Promise((resove,reject)={...})
- 任务成功则调用resove(result)
- 任务失败则调用reject(error)
- resove和reject再去调用成功和失败函数
- 使用.then(sucess,fail)传入成功和失败函数
3.Promise.prototype.then用法
Promise.prototype.then()简写为.then(),可以采用链式写法:
AJAX('get','/xxx').then(()=>{},()=>{}).then(()=>{},()=>{})....
- then方法的第一个参数是resolved状态的回调函数
- 第二个参数(可选)是rejected状态的回调函数
例1:
getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});
- 上面的代码使用then方法,依次指定了两个回调函数
- 第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数
例2:
getJSON("/post/1.json").then(
post => getJSON(post.commentURL)
).then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
);
- 第一个then方法指定的回调函数,返回的是另一个Promise对象
- 第二个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化
- 如果这个Promise对象状态变为resolved,就调用第一个回调函数,若为rejected 就调用第二个回调函数
4.Promise.all用法
Promise.all()方法用于将多个 Promise 对象,包装成一个新的 Promise 对象。
const p = Promise.all([p1, p2, p3])
- p1、p2、p3都是 Promise实例
- 如果不是,则调用Promise.resolve方法,将参数转为 Promise实例
- p1、p2、p3 可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise实例
- 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、 p3的返回值组成一个数组,传递给p的回调函数
- 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被 reject的实例的返回值,会传递给p的回调函数
5.Promise.race用法
Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.race([p1, p2, p3]);
- p1、p2、p3都是 Promise实例
- 如果不是,则调用Promise.resolve方法,将参数转为 Promise实例
- 只要p1、p2、p3之中有一个实例先改变状态,p的状态就跟着改变。那个先改变的 Promise 实例的返回值,就传递给p的回调函数