Tur*_*lov 1 javascript asynchronous promise
在js中遇到过一篇关于promises的文章,作者展示了一段代码:
// 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!
});
Run Code Online (Sandbox Code Playgroud)
并说
这段代码有什么问题?问题是第一个函数实际上返回的是 undefined,这意味着第二个函数不会等待 db.remove() 在所有文档上被调用。事实上,它不等待任何东西,并且可以在删除任意数量的文档时执行!
所以,据我所知,如果第二个回调不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"));
Run Code Online (Sandbox Code Playgroud)
我等待“更早调用”出现在打印数字的中间。但不管项目的数量有多大。“较早调用”总是出现在最后。有人可以解释我缺少什么吗?也许这篇文章已经过时了,从那以后发生了一些变化?
为了保证这一点,您实际上必须从先前的承诺中返回承诺。
无论你从一个 promise 中返回什么,都会被传递到下一个 promise。
在你的情况下,你回来了undefined。
相反,如果你返回了一个 promise,那么这个 promise 就会被解析,第二个 promise 会在这之后运行,并且会传递 promise 解析的任何值。
所以是的,promise 保证会一个接一个地运行,但是如果你选择在它们的回调中做一些异步的事情,并且不要通过返回它来将它链接回 promise,那么它们就不会费心等待为任何事情(因为他们不知道有什么可等待的)。
我假设db.remove返回一个承诺......
...所以,知道我们必须从回调中返回一个承诺,以便它真正等待异步事件的发生,我会做这样的事情。
.then(result => Promise.all(result.rows.map(row => db.remove(row.doc))))
.then((listOfRemoves) => console.log(`removed`));
Run Code Online (Sandbox Code Playgroud)
第二个函数是否接受 1 个参数或 0 个参数对于第二个函数何时运行是 100% 无关紧要的。
例子:
.then(() => setTimeout(() => console.log('2nd', 20000)))
.then(() => console.log('first'));
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为第一个然后不知道发生了 setTimeout。它不是读心者,它只是运行代码并传递返回值(在本例中为undefined)。
但是,如果返回值恰好是一个 Promise,它会等到该 Promise 完成,从中获取值,然后将其传递。
.then(() => new Promise(resolve => setTimeout(resolve, 20000)))
.then(() => console.log('I waited 20 seconds.'));
Run Code Online (Sandbox Code Playgroud)
因为它返回一个promise,它会调用then那个promise 的 ,并等待获取值,然后传递。
你的测试失败的原因是因为你基本上是这样做的。
.then(() => console.log('first'))
.then(() => console.log('second'));
Run Code Online (Sandbox Code Playgroud)
这些保证按此顺序触发。时期。所有其他人也都按这个顺序开火。只是他们也在调度异步进程,就像所有其他在 JS 中使用异步 I/O 的回调/超时一样。
| 归档时间: |
|
| 查看次数: |
647 次 |
| 最近记录: |