我有以下异步代码示例:
// 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
问题:为什么当我们在someWrapper()
(test2)中使用函数for-loop
时,我们得到的结果与我们将此函数体直接复制粘贴到{{1}中的结果不同(test1)?
(上面的例子非常抽象,但是#34;我发现这种行为&#34;在调用ajax请求时(而不是for-loop
和console.log('A: '+ i);
)哪个序列在我的应用中非常重要(请求console.log('B: '+ i);
必须在请求之前A1
...))
答案 0 :(得分:2)
<强> TEST2:强>
你的test2在异步之前不是异步的。你在test2.they中编写了同步代码,它们是console.log。只有test2中的异步代码才能调用promise.Let将其分解
async function test2() {
for(let i=0; i<5; i++) {
someWrapper(i);
}
}
上面的代码按顺序触发someWrapper()5次。然后编写第一个 sync
代码 console.log('A'+i)
5次在控制台中连续。
然后每个 someWrapper()等待 async
承诺返回并行。在每个承诺解决后,它会打印出“内部承诺” ”。 直到承诺结算,执行停止,无法进入下一步
然后,在解析承诺后,它会在控制台
中输出第二个sync
代码 console.log('B'+i)
<强> TEST1:强>
test1的行为与test2不同。让它分解
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);
}
}
主要区别在于您 awaiting inside for loop
。所以这将 pause
loop
,而 test1
因此,对于每次迭代,它都会打印 console.log('A'+i)
然后暂停 await getSomePromise()
当承诺返回时会打印'Inside Promise'
然后打印 console.log('B'+i)
然后继续下一次迭代。
答案 1 :(得分:2)
查看评论
@HMR - 嗯...我不明白 - 在问题的例子中有异步 函数someWrapper()但该函数不返回任何东西(它 甚至没有退货声明(!)) - 你能解释一下你是什么 是
async functions immediately return a promise
的意思? - Kamil Kielczewski
似乎你不理解异步等待。我通常会建议人们等待,直到你明白承诺。但是,在下一个有问题的评论中,我给出了答案:
someWrapper将立即返回解析为的承诺 未定义。等待只在someWrapper函数中“等待”,但是 函数调用someWrapper会立即收到一个承诺 解决方案未定义。如果不这样做,函数总会返回一些东西 在代码中,它将返回undefined。如果它是异步功能 没有回报然后它将返回一个解决的承诺 undefined - HMR。
Await是承诺的语法糖(更好看的代码),实际上并没有等待任何事情。
以下代码可能会清除:
var test = async () => {
await 22;//doesn't even matter if value is promise
console.log("after wait");
}
var result = test();
console.log("outside test we don't wait for anything",result);
如果你不明白为什么那段代码的输出是:
外部测试我们不等任何Promise {&lt;待定&gt;}
等待后
然后我建议你只使用承诺,直到你这样做。