【发布时间】:2018-07-18 03:00:51
【问题描述】:
我有以下异步代码示例:
// Functions
function getSomePromise() {
let a = new Promise((resolve, reject) => {
setTimeout(function(){
console.log("Inside promise...");
resolve("Success!");
}, 1000);
});
return a;
}
async function someWrapper(i) {
console.log('A: '+ i);
await getSomePromise();
console.log('B: ' + i);
}
还有两个测试:
async function test1() {
for(let i=0; i<5; i++) {
// body copy-pasted of someWrapper function:
console.log('A: '+ i);
await getSomePromise();
console.log('B: ' + i);
}
}
async function test2() {
for(let i=0; i<5; i++) {
someWrapper(i);
}
}
这是运行 separatley test1() 和 test2() 后 chrome 控制台中的结果:
Test 1 | Test 2
---------------------------------------------
A: 0 | A: 0
Inside promise... | A: 1
B: 0 | A: 2
A: 1 | A: 3
Inside promise... | A: 4
B: 1 | Inside promise...
A: 2 | B: 0
Inside promise... | Inside promise...
B: 2 | B: 1
A: 3 | Inside promise...
Inside promise... | B: 2
B: 3 | Inside promise...
A: 4 | B: 3
Inside promise... | Inside promise...
B: 4 | B: 4
问题:为什么当我们在 for-loop (test2) 中使用函数 someWrapper() 时,我们得到的结果与我们将这个函数体直接复制粘贴到 for-loop (test1) 中的结果不同?
(上面的例子非常抽象,但是在调用 ajax 请求(而不是 console.log('A: '+ i); 和 console.log('B: '+ i);)时“我发现了这种行为”,这在我的应用程序中非常重要(请求 A1 必须在请求 @987654332 之前@...))
【问题讨论】:
-
您的第一个测试使用
async和await,它们按顺序运行promise。第二个测试没有,所以每个 Promise 都会开始,然后按顺序完成。 -
@Sidney 你能详细说明一下吗——在我看来——我在 someWrapper() 和 Test2() 中使用异步/等待,我以同步(通过 for 循环)方式调用这个函数。跨度>
-
在第一个测试循环中,
await导致循环在getSomePromise()函数处暂停,直到 promise 解决。在第二个测试中,没有await,所以JavaScript 在启动每个promise 后愉快地继续循环。如果不在函数中使用await,则创建函数async并没有真正做任何事情。 -
@Sidney 唯一的区别是我将循环体(在测试 1 中)移动到功能(测试2)。在我看来,这种行为是违反直觉的——你同意吗?
-
someWrapper 将立即返回一个解析为未定义的承诺。 await 仅在 someWrapper 函数中“等待”,但调用 someWrapper 的函数将立即收到一个以 undefined 解析的承诺。函数总是返回一些东西,如果你不在代码中,那么它将返回未定义的。如果它是一个没有返回的异步函数,那么它将返回一个以 undefined 解析的承诺。
标签: javascript function asynchronous es6-promise