了解是什么触发了移动到javascript承诺链的下一个.then()。

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

我有一个承诺链,看起来像这样。

fistAsyncFunction()
    .then(() => {
        secondAsyncFunction()
    })
    .then(() => {
        thirdAsyncFunction()
    })

我注意到第三个异步函数在第二个异步函数完成之前就开始了,但是把它改成这样之后,它就按照我的要求工作了。

fistAsyncFunction()
    .then(() => {
        return secondAsyncFunction()
    })
    .then(() => {
        thirdAsyncFunction()
    })

似乎即使第二个异步函数没有返回任何东西,程序也在等待它返回。undefined 然后再进行下一个承诺。这是实际发生的事情吗?如果不是,那么到底发生了什么,提示javascript开始执行下一个承诺?

javascript asynchronous promise chaining
1个回答
1
投票

可以这样想

fistAsyncFunction()
    .then(() => {
        secondAsyncFunction()
        return undefined
    })
    .then((iAmUndefined) => {
        thirdAsyncFunction()
        return undefined
    })

^ 这是你的第一个使用显式返回的例子。

看起来即使第二个async函数没有返回任何东西,程序也在等待它返回undefined后再进入下一个承诺。

所以你这个算是说对了。第二个async函数没有返回任何东西,这是正确的。然而,程序并没有等待 secondAsyncFunction() 来返回未定义。而且,它不会等待 secondAsyncFunction() 完全没有。相反,你的程序在说

好吧,我知道了 secondAsyncFunction 我现在就给你打电话,让你跑了,我不会等你。相反,我只会返回undefined,然后继续前进。喂 thirdAsyncFunction!

你是正确的,在注意到你的 thirdAsyncFunction 是在你之前开始的 secondAsyncFunction 返回。

接下来,你对你的代码进行了修改,以实现你的预期行为。

fistAsyncFunction()
    .then(() => {
        return secondAsyncFunction()
    })
    .then(resultOfSecondAsyncFunction => {
        thirdAsyncFunction()
        return undefined
    })

^ 这是你的第二个例子,有明确的回报

你的程序现在正在以你想要的方式工作,因为通过返回 secondAsyncFunction()现在,你正在指示你的程序等待该函数的返回。

到底发生了什么,让javascript开始执行下一个承诺?

在下面,有一个特殊的函数 resolve 中的 Promise 构造函数。的时候,下一个承诺将开始执行。resolve 的函数被调用。当然,这两个承诺必须由一个 .then.


1
投票

当你有一个像这样的承诺链。

fn1().then(() => {
    fn2();
}).then(() => {
    fn3();
});

这就是事件的顺序:

  1. fn1() 执行并返回一个承诺(我称之为 p1).
  2. 使用该返回的承诺 p1జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ .then() 方法被调用,该方法简单地存储了一个回调,并立即返回另一个许诺 p2.
  3. 使用该返回的承诺 p2జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ .then() 方法被调用,该方法简单地存储了一个回调,并立即返回另一个许诺 p3 不被任何东西保存或使用)。
  4. 之后的某个时候 p1 解决了。 这将导致之前保存的 .then() 处理程序被调用。
  5. .then() 处理程序运行它里面的代码。 在这个特定的例子中,它调用了 fn2(). 但是,由于 fn2() 也是异步的,它只是开始操作,然后立即返回一个承诺。 但是,在这个特殊的代码示例中,没有任何东西在看那个返回的承诺,所以没有使用它。 然后,执行从 .then() 处理程序返回到最初调用它的承诺。 该承诺查看了来自 .then() 处理器,并发现它 undefined. 既然这里没有额外的承诺可以等待,那么就解决自己的承诺吧 p2.
  6. p2 解决了,它就会调用它的 .then() 处理程序,它开始 fn3(). 现在你将同时拥有 fn2()fn3() 在飞行中同时进行,哪一个先完成将是不确定的(这实际上只是两个异步操作之间的竞赛)。

当你改为这样做的时候。

fn1().then(() => {
    return fn2();
}).then(() => {
    return fn3();
});

那么,在第五步之前,一切都一样。 但是,在这个例子的第5步中,第一个 .then() 处理人 return fn2(). 所以.., fn2() 被调用,就像前面的例子一样,它返回一个承诺,而这个承诺是从 .then() 处理程序。 这就告诉宿主承诺,它需要等到that promise也解析后再继续承诺链。

所以,如果你在一个叫做 .then() 处理程序,并且你想让承诺链等待它们,你必须返回一个从 .then() 处理程序,该处理程序链接到你的内部异步操作。 如果你不这样做,那么这些额外的异步操作只是 "fire and forget",因为没有任何东西会关注它们何时完成或是否有错误。

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