我对Promise的理解

161 阅读3分钟

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的回调函数