gpt4 book ai didi

javascript - promise 链如何开始和结束

转载 作者:行者123 更新时间:2023-11-28 18:08:04 25 4
gpt4 key购买 nike

我对我遇到的各种文档中的排序如何工作感到有些困惑。比如我见过这样的事情

let p = Promise.resolve();
for (let x in something)
{
/* do some hairy time consuming code */
p = p.then(dosomething(x));
}
return p.then(finalthing()).catch(pretendnobadthing());

我真正不明白的是,如果您在主代码中做一些需要大量时间的事情,这是否意味着其中一个 promise 可以在主代码实际开始设置之前完成。然后。

您是否可以始终在 promise 上使用 .then/.catch ,如果它已经完成,它将从它到达的点继续,所以它在概念上看起来像一个大链,将在某个不确定的点运行到完成?如果是这样,这是否意味着每次您创建一个 promise 链时,它都会永远挂起?

最佳答案

Can you always use .then/.catch on a promise, and if its already reached completion, it'll carry on from the point it got to, so it conceptually looks like a big chain that will run to completion at some indeterminate point?



是的,你总是可以在 promise 上使用 .then/.catch。当您调用 p.then() ,有三种可能。
  • promise p仍待处理(尚未完成或拒绝)。如果是这种情况,那么您传递给 .then() 的函数引用注册为该 promise 的监听器。因此,当 future 的状态转换发生在 Promise 上时(要么从挂起 => 已完成或从挂起 => 拒绝),那么将调用适当的注册监听器。
  • promise p已经实现。如果是这种情况,请调用 .then(f1, f2)将安排f1在下一个滴答声中调用(在当前的 Javascript 完成执行后),它将传递保存的解析值。
  • promise p已经被拒绝了。如果是这种情况,请调用 .then(f1, f2)将安排f2在下一个滴答声中被调用(在当前的 Javascript 完成执行之后),它将传递保存的拒绝原因。

  • 所以,调用 .then() 是绝对安全的。在已经履行或拒绝的 promise 上。适当的监听器将被安排在下一个滴答时运行。

    同样的逻辑适用于 .catch()除了它只对上面的案例 1 和 3 感兴趣。

    这里是

    And if so, doesn't that mean every time you create a promise chain it'll hang about for ever?



    Promise 只是对象,就像 Javascript 中的任何其他对象一样。只有当其他代码仍然对它们有一些实时引用时,它们才会徘徊。一旦不再有任何方法可以到达该 promise 对象,它们将有资格进行垃圾收集,就像 Javascript 中的任何其他对象一样。

    所以,如果你这样做:
    var p = somePromiseReturningFunction();

    p.then(f1).then(f2).then(f3);

    然后, p将一直保留到 somePromiseReturningFunction()完成对它返回的 promise 的任何引用(通常,尽管不总是,这发生在 promise 最终被履行或拒绝时)和变量 p超出范围。如果 p永远不会超出范围(比如当它是全局的或其他持久的范围时),那么它将永远存在(就像任何其他 Javascript 对象一样)。

    您的问题存在一些误解,所以让我尝试解决这些问题。

    您正在使用构造 p = p.then(dosomething(x));这可能是不正确的。您需要通过 .then()函数引用。所以,除非你想要 doSomething(x)立即执行,它还返回另一个你想要调用的函数,然后 .then()处理程序(这里似乎不太可能),那么这不是正确的构造。您可能打算拥有:
    p = p.then(result => dosomething(x));

    或者在 ES5 语法中:
    p = p.then(function(result) {
    return dosomething(x)
    });

    您也显示了同样的问题:
    return p.then(finalthing()).catch(pretendnobadthing());

    这可能应该是:
    return p.then(finalthing).catch(pretendnobadthing);

    请记住,当您使用 f() ,即执行 f立即地。当你刚刚通过 f ,它传递一个函数引用,你传递给它的底层函数/方法可以稍后在它选择时调用,这就是你想要的 .then().catch()处理程序。

    What I really don't understand is that if you do something that takes a large amount of time in the main code, wouldn't that mean that one of the promises could complete before the main code actually got round to to setting up the .then.



    首先,我在答案开头的原始解释应该解释调用 .then()在一个已经解决的 promise 上完全没问题,所以这根本不是问题。它只会在事件循环的下一个滴答声中安排 Action 。

    但是,这里甚至不是这种情况,因为浏览器和 node.js 中的 Javascript 是单线程的,因此当您的长时间运行的代码正在运行时,该 promise (谁的异步操作之前已启动)尚未得到解决。虽然底层的异步操作可能已经完成,并且一个事件可能位于 Javascript 事件队列中,该事件将触发一个回调来解决 promise ,但事件队列中的事件直到当前正在执行的 Javascript 片段才会得到处理完成并将控制权返回给系统。

    关于javascript - promise 链如何开始和结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42193985/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com