Promise 知识梳理

1. Promise用法详解

new Promise(
  /* 执行器 executor */
  function (resolve, reject) {
    // 一段可能耗时很长的异步操作
    doAsyncAction(function callback(err, result) {
      if (err) {
        return reject(err);
      }
      resolve(result);
    });
  }
)
  .then(function resolve() {
    // 成功,下一步
  }, function reject() {
    // 失败,做相应处理
  });复制代码


Promise 实例有三个状态:

  1. pending [待定] 初始状态,新创建的实例处于这个状态
  2. fulfilled [实现] 操作成功,在执行器里调用 resolve() 之后,实例切换到这个状态
  3. rejected [被否决] 操作失败,在执行器里调用 reject() 之后,实例切换到这个状态

2. .then()

.then() 其实接受两个函数作为参数,分别代表 fulfilled 状态时的处理函数和 rejected 状态时的处理函数, .then() 会返回一个新的 Promise 实例,所以它可以链式调用,如前面的例子所示。当前面的 Promise 状态改变时,.then() 会执行特定的状态响应函数,并将其结果,调用自己的 Promise 的 resolve() 返回。

注意: Promise.resolve() 在返回为null时,会返回一个状态为 fulfilled 的 Promise

几个例子:假定 doSomething()doSomethingElse() 都会返回 Promise 对象

第一题

doSomething()
  .then(function () {
    return doSomethingElse();
  })
  .then(finalHandler);复制代码

答案:

doSomething
|-----------|
            doSomethingElse(undefined)
            |------------|
                         finalHandler(resultOfDoSomethingElse)
                         |------------|
复制代码

第二题

doSomething()
  .then(function () {
    doSomethingElse();
  })
  .then(finalHandler);复制代码

答案:

doSomething
|-----------------|
                  doSomethingElse(undefined)
                  |------------------|
                  finalHandler(undefined)
                  |------------------|
复制代码

这道题就有一定难度了。虽然 doSomethingElse 会返回 Promise 对象,但是因为 .then() 的响应函数并没有把它 return 出来,所以这里其实相当于 return null。我们知道,Promise.resolve() 在参数为空的时候会返回一个状态为 fulfilled 的 Promise,所以这里两步是几乎一起执行的。

第三题

doSomething()
  .then(doSomethingElse())
  .then(finalHandler);复制代码

答案:

doSomething
|-----------------|
doSomethingElse(undefined)
|---------------------------------|
                  finalHandler(resultOfDoSomething)
                  |------------------|
复制代码

这一题的语法陷阱也不小。首先,doSomethingElsedoSomethingElse() 的区别在于,前者是变量,指向一个函数;而后者是则是直接执行了函数,并返回其返回值。所以这里 doSomethingElse 立刻就开始执行了,和前面 doSomething 的启动时间相差无几,可以忽略不计。然后,按照 Promise 的设计,当 .then() 的参数不是函数的时候,这一步会被忽略不计,所以 doSomething 完成后就跳去执行 finalHandler 了。

第四题

doSomething()
  .then(doSomethingElse)
  .then(finalHandler);复制代码

答案:

doSomething
|-----------|
            doSomethingElse(resultOfDoSomething)
            |------------|
                         finalHandler(resultOfDoSomethingElse)
                         |------------------|复制代码

3. .catch()

使用方法:

doSomething()
  .doAnotherThing()
  .doMoreThing()
  .catch( err => {
    console.log(err);
  });复制代码


注意:
 一旦 resolve() 方法中抛出了错误,会跳过后面 .then(),进入 .catch() 处理异常。
catch() 后的 .then() 方法仍能继续执行。
new Promise(resolve => {
  setTimeout(() => {
    resolve();
  }, 1000);
})
  .then( () => {
    console.log('start');
    throw new Error('test error');
  })
  .catch( err => {
    console.log('I catch: ', err);

    // 下面这一行的注释将引发不同的走向
    // throw new Error('another error');
  })
  .then( () => {
    console.log('arrive here');
  })
  .then( () => {
    console.log('... and here');
  })
  .catch( err => {
    console.log('No, I catch: ', err);
  });

// 输出:
// start
// I catch: test err
// arrive here
// ... and here复制代码

4. Promise.all()

Promise.all(promiseArray)方法是Promise对象上的静态方法,该方法的作用是将多个Promise对象实例包装,生成并返回一个新的Promise实例。

var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    console.log(results);  // [1, 2, 3]
});复制代码

在上面的方法中,promise数组中所有的promise实例都变为resolve的时候,该方法才会返回,并将所有结果传递results数组中。promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象。reject使用示例如下:

var p1 = Promise.resolve(1),
    p2 = Promise.reject(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    //then方法不会被执行
    console.log(results); 
}).catch(function (e){
    //catch方法将会被执行,输出结果为:2
    console.log(e);
});复制代码

5. Promise 实现队列

1. 使用 forEach

function queue(things) {  let promise = Promise.resolve();  things.forEach(thing => {    promise = promise.then(() => {      return new Promise(resolve => {        doThing(thing, () => {          resolve();        })      })    })  })}
queue([1, 2, 3, 4]);复制代码

2. 使用 reduce

function queue(things) {  return things.reduce(promise, thing => {    return promise.then(() => {      return new Promise(resolve => {        doThing(thing, () => {          resolve();        })      })    })  }, Promise.resolve())}
queue([1, 2, 3, 4]);复制代码

6. Promise.resolve()/reject()/race()使用

7. Promise兼容性问题

bluebird

promise polyfill

8. ES2017 async() 、await()


附录:

Promise 入门视频教程

javascript-async-tutorial


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值