我有以下异步代码示例:
// 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);
}
}
下面是运行separatleytest1()
和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
必须在请求B0
之前...))
测试2:
在使test2异步之前,它不是异步的。您已经在test2中编写了同步代码。它们是控制台。日志test2中只有异步代码是对promise的调用。让我们把它分解一下
async function test2() {
for(let i=0; i<5; i++) {
someWrapper(i);
}
}
上面的代码按顺序激发someWrapper()5次。因此,它编写第一个sync
代码,即控制台。在控制台中连续记录('A'i)
5次。
然后,每个某物Wrapper()等待async
promise返回parallelly.after每个promise解决它打印的内部promise。直到promise解决,执行停止,不能继续下一步
然后,在解析promise后,它打印出控制台中的第二个sync
代码,即console.log('B'i)
测试1:
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);
}
}
主要区别在于您正在等待内部for循环
。因此,这实际上将暂停循环
,而
test1的情况并非如此
因此,对于每个迭代,它将打印
控制台。日志('A'i)
然后暂停迭代,等待getSomePromise()
promise返回时将打印“内部promise”
然后打印
控制台。日志('B'i)
然后继续下一次迭代。
看着评论
@HMR-hm。。。我不明白-在有问题的示例中,有一个异步函数someWrapper(),但该函数不返回任何东西(它甚至没有return语句(!)-你能解释一下异步函数立即返回promise是什么意思吗卡米尔·基尔切夫斯基
似乎您不理解异步等待。我通常建议人们停止工作,等待你明白promise。然而,在下一个问题下的评论中,我给你答案:
someWrapper将立即返回解析为未定义的promise。someWrapper函数中的wait only“waitis”,但调用someWrapper的函数将立即收到一个在未定义中解析的promise。函数总是返回一些东西,如果在代码中没有,那么它将返回未定义的。如果它是一个没有返回的异步函数,那么它将返回一个在undefined-HMR中解析的promise。
wait是promise的语法糖(外观更好的代码),实际上并不等待任何东西。
也许下面的代码可以清除这些内容:
js prettyprint-override">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);
我正试图将图像上传到firebase存储,但调用该函数时,未执行wait以获取url。我错过了什么? 看看这个其他主题,我发现问题可能是“然后”,但我如何设置代码以等待url? 异步/等待/然后飞镖/颤振 谢谢
问题内容: 目前,我正在尝试在类构造函数中使用。这样一来,我就可以为正在从事的Electron项目获取自定义标签。 但是,目前该项目无法正常工作,并出现以下错误: 有没有办法避免这种情况,以便我可以在其中使用异步/等待?而不需要回调或.then()? 问题答案: 这 永远 行不通。 该关键字允许在标记为函数中使用,但它也是功能转换成一个承诺发生器。因此,标有的函数将返回承诺。另一方面,构造函数返回
我试图在react/electron项目中使用async/await,但它不起作用。我想要的是获取docker容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)
问题内容: 我知道这个问题以前曾被问过,但是所有解决方案都不适合我。 我有一个将参数发送到API的函数,并以列表的形式返回数据。我有一个UITableView设置为使用该列表,但是它在列表分配给变量之前运行。 码: 如果不立即将其作为重复投票,我将不胜感激,这是我尝试的方法。 派遣组 信号量计时 运行变量 其中包括= self和= self 。 编辑:要求提取项目, 问题答案: 您不能-也不应该-
我试图为从服务调用异步函数的函数编写测试,但我一辈子都不知道如何让Jasmine在执行expect函数之前等待异步操作完成。 我试图使用Jasmine的“完成”功能,但我不知道如何实现它。 在本例中,只要 调用时,它立即跳转到expect并失败,因为异步操作尚未完成。
问题内容: 我的代码在javascript中看起来像这样: 在完成所有这些异步调用之后,我想计算所有数组的最小值。 我要如何等待所有人? 我现在唯一的想法是拥有一个名为done的布尔数组,并在第i个回调函数中将done [i]设置为true,然后说while(不是全部都完成了){} 编辑:我想一个可能但很丑陋的解决方案是在每个回调中编辑完了的数组,然后如果每个回调中都设置了所有其他完成,则调用一个