为什么 `promise.finally` 在调用者的 `then` 之后执行?

问题描述 投票:0回答:1

考虑一下:

const a = () => {
  return new Promise((resolve) => {
    resolve(1);
  });
};

const b = () => {
  return new Promise((resolve) => {
    a()
      .then((aR) => {
        console.log(aR);
        resolve(2);
      })
      .finally(() => {
        console.log("A");
      });
  });
};

const c = () => {
  b().then((bR) => {
    console.log(bR);
  });
};

c();

为什么会打印

1 2 A
not 1 A 2


这个问题最初是由@rebuilding127在类似StackOverflow的中文论坛Segmentfault上发现的。我认为值得在这里翻译和发布。

javascript asynchronous promise es6-promise
1个回答
0
投票

你可以看到这个链式调用:

    a()
      .then((aR) => {
        console.log(aR);
        resolve(2);
      })
      .finally(() => {
        console.log("A");
      });

这是一个链式调用,其中

a().then(...)
返回一个
Promise
,它将在返回的
A
满足后输出
Promise
,而不是在
a()
满足后输出。因此,在满足
resolve(2)
并入队
b().then
之前,
a().then
将入队
a().finally

为了更清楚,我重写了代码:

const f = () => {
  const a = new Promise((resolve) => {
    const cb1 = (result1) => {
      console.log(result1);
      resolve(2);
    };
    const cbA = () => console.log('A');
    const b = Promise.resolve(1);
    const c = b.then(cb1);
    c.finally(cbA);
  });
  return a;
};

const cb2 = (result2) => console.log(result2);
f().then(cb2);

执行过程如下:

  1. 开始执行
    f
  2. 开始执行
    a
  3. b
    立即得到满足,导致
    cb1
    被排入微任务队列(现在队列 =
    [cb1]
  4. c
    的执行者入队
  5. f
    回归
  6. 开始从队列执行
    cb1
    (现在队列=
    []
  7. 输出
    1
    ,解析
    a
    ,导致
    cb2
    入队(现在队列 =
    [cb2]
  8. cb1
    返回,导致
    c
    被解析,然后
    cbA
    被排队(现在队列 =
    [cb2, cbA]
  9. 开始从队列执行
    cb2
    (现在队列=
    [cbA]
  10. 输出
    2
  11. 从队列中开始执行
    cbA
    ;现在队列 =
    []
    .
  12. 输出
    A
    ,勾选结束

还在 SegmentFault 上的原始问题下发布了

© www.soinside.com 2019 - 2024. All rights reserved.