Promise的局限性和解决方案

3/2/2023

# Promise的局限性

  • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

# 解决方案

  • 为Promise对象添加一个取消方法,可以取消Promise的执行。
  • 为Promise对象添加一个状态方法,可以获取Promise的状态。
  • 为Promise对象添加一个进度方法,可以获取Promise的进度。

# async/await语法

async/await是ES2017标准引入的新语法,它可以让异步操作变得更加简单。async/awaitPromise的语法糖,它的本质是Generator函数的语法糖。

# async/await的使用

async关键字用于声明一个函数是异步函数,await关键字用于等待一个异步操作完成。async/await的使用方式如下:

async function asyncFunc() {
  // ...
}

const asyncFunc = async function() {
  // ...
}

const asyncFunc = async () => {
  // ...
}
1
2
3
4
5
6
7
8
9
10
11
async function asyncFunc() {
  const result = await asyncOperation();
  // ...
}
1
2
3
4

# async/await的原理

async/await的原理是基于Promise的,它的本质是Generator函数的语法糖。async/await的实现原理如下:

function asyncFunc() {
  return spawn(function* () {
    const result = yield asyncOperation();
    // ...
  });
}

function spawn(genF) {
  return new Promise(function(resolve, reject) {
    const gen = genF();
    function step(nextF) {
      let next;
      try {
        next = nextF();
      } catch(e) {
        return reject(e);
      }
      if (next.done) {
        return resolve(next.value);
      }
      Promise.resolve(next.value).then(function(v) {
        step(function() { return gen.next(v); });
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }
    step(function() { return gen.next(undefined); });
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# async/await的优缺点

  • 优点

    • 语义化更好,更加直观。
    • 内置执行器,更加方便。
    • 更好的语义。
    • 错误处理更加方便。
  • 缺点

    • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
    • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
    • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
    • 需要使用babel转码器,才能在浏览器中使用。
编辑时间: 4/12/2016, 9:05:20 AM