javascript - promise 链是否保证仅在前一个 promise 完成后才调用下一个 promise 的回调?

标签 javascript asynchronous promise

我遇到了一个article about promises in js ,作者展示了一段代码:

// I want to remove() all docs
db.allDocs({include_docs: true}).then(function (result) {
  result.rows.forEach(function (row) {
    db.remove(row.doc);  
  });
}).then(function () {
  // I naively believe all docs have been removed() now!
});

What's the problem with this code? The problem is that the first function is actually returning undefined, meaning that the second function isn't waiting for db.remove() to be called on all the documents. In fact, it isn't waiting on anything, and can execute when any number of docs have been removed!

因此,据我了解,如果第二个回调 function() {} 不接受任何参数,它实际上不会等待回调结束 function(result)。我推断正确吗?因为当我运行以下代码时,它给出了相反的结果:

var array = [];
for ( let i = 0; i < 1000; i++ )
    array.push(i);

var promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve(), 1000);
});

promise
.then(() => array.forEach(item => console.log(item)))
.then(() => console.log("invoked earlier"));

我等待“invoked earlier”出现在打印数字的中间。但是项目的数量有多大并不重要。 “较早调用”总是出现在最后。有人可以向我解释我所缺少的吗?也许这篇文章已经过时并且从那以后发生了一些变化?

最佳答案

为了保证这一点,您实际上必须返回之前 promise 的 promise 。

无论您从一个 promise 中返回什么,都将传递到下一个 promise。

在您的例子中,您将返回 undefined

相反,如果您返回一个 promise,那么该 promise 将被解析,第二个 promise 将在该事件发生后运行,并将传递该 promise 解析的任何值。

所以是的,promises 保证一个接一个地运行,但是如果你选择在它们的回调中做一些异步的事情,并且不费心通过返回它把它链接回 promise,那么它们就不会懒得等待任何事情(因为他们不知道还有什么要等待)。

我假设 db.remove 返回一个 promise ...

...所以,知道我们必须从回调中返回一个 promise ,以便它真正等待异步事情发生,我会做这样的事情。

.then(result => Promise.all(result.rows.map(row => db.remove(row.doc))))
.then((listOfRemoves) => console.log(`removed`));

对于第二个函数何时运行,第二个函数是采用 1 个参数还是 0 个参数 100% 无关紧要。

编辑

例子:

.then(() => setTimeout(() => console.log('2nd', 20000)))
.then(() => console.log('first'));

发生这种情况是因为第一个不知道发生了 setTimeout。它不是读心器,它只是运行代码并传递返回值(在本例中为 undefined)。

如果返回值恰好是一个 promise,它会等到该 promise 完成,从中获取值,然后传递那个

.then(() => new Promise(resolve => setTimeout(resolve, 20000)))
.then(() => console.log('I waited 20 seconds.'));

因为它正在返回一个 promise ,所以它会调用该 promise 的 then,并等待获取值,然后继续传递。

你的测试失败的原因是因为你基本上是这样做的。

.then(() => console.log('first'))
.then(() => console.log('second'));

这些保证按此顺序触发。时期。 所有其他人也都按照这个顺序开火。只是它们调度异步进程,就像在 JS 中使用异步 I/O 的所有其他回调/超时一样。

关于javascript - promise 链是否保证仅在前一个 promise 完成后才调用下一个 promise 的回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44986050/

相关文章:

java - 如何跟踪在多个服务器中运行的异步任务的进度状态

asynchronous - 如何像生成器一样使用异步协程?

javascript - 在 promise 中 react setState 导致无限循环

javascript - 用于动画和更新 div 的 ui slider

javascript - jQuery - 单击时从 div 获取数据

php - 需要在 php 代码中插入 javascript [Wordpress Website]

javascript - 通过 JS 统一 API 获取主题列表

javascript - 使用 jquery 和数据库检查更改

javascript - 负载过大时 typescript 异步功能不起作用

javascript - 隐式事件对象传入错误事件监听器