Javascript 异步等待函数的奇怪行为

Javascript 异步等待函数的奇怪行为,javascript,function,asynchronous,es6-promise,Javascript,Function,Asynchronous,Es6 Promise,我有以下异步代码示例: // Functions function getSomePromise() { let a = new Promise((resolve, reject) => { setTimeout(function(){ console.log("Inside promise..."); resolve("Success!"); }, 1000); });

我有以下异步代码示例:

// 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);                
    }    
}
问题:为什么在
for loop
(test2)中使用函数
someWrapper()
,得到的结果与我们复制粘贴这个函数体直接到
for loop
(test1)中的结果不同


(上面的示例非常抽象,但是在调用ajax请求时“我发现了这种行为”(而不是
console.log('A:'+I);
console.log('B:'+I);
)在我的应用程序中,哪个序列非常重要(请求
A1
必须在请求
B0
之前)

test2:

在使test2异步之前,它不是异步的。您已经在test2中编写了同步代码。它们是console.log。test2中唯一的异步代码是对promise的调用。让我们把它分解一下

async function test2() {
    for(let i=0; i<5; i++) {
        someWrapper(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);
    }    
}
主要区别在于您正在等待内部for循环。因此,这实际上将暂停
循环
,而
测试1的情况并非如此

因此,对于每个迭代,它将打印控制台.log('A'+i)

然后暂停迭代,等待getSomePromise()

承诺返回时将打印“内部承诺”

然后打印console.log('B'+i)


然后继续下一次迭代。

test2:

在使test2异步之前,它不是异步的。您已经在test2中编写了同步代码。它们是console.log。test2中唯一的异步代码是对promise的调用。让我们把它分解一下

async function test2() {
    for(let i=0; i<5; i++) {
        someWrapper(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);
    }    
}
主要区别在于您正在等待内部for循环。因此,这实际上将暂停
循环
,而
测试1的情况并非如此

因此,对于每个迭代,它将打印控制台.log('A'+i)

然后暂停迭代,等待getSomePromise()

承诺返回时将打印“内部承诺”

然后打印console.log('B'+i)


然后继续下一次迭代。

查看注释

@HMR-hm。。。我不明白-有问题的例子是异步的 函数someWrapper(),但该函数不返回任何内容(它 甚至没有返回声明(!)-你能解释一下你的想法吗 异步函数立即返回承诺的意思是?-卡米尔·基尔切夫斯基

似乎您不理解异步等待。我通常建议人们停止工作,等待你明白承诺。然而,在下一个问题下的评论中,我给你答案:


someWrapper将立即返回一个承诺,该承诺将 未定义。wait仅在someWrapper函数中“waitis”,但
调用someWrapper的函数将立即收到一个承诺 解析为未定义。函数总是返回一些东西,如果您不这样做的话 在代码中,它将返回undefined。如果它是一个异步函数 如果没有回报,那么它将回报一个最终解决的承诺 未定义-HMR

wait是承诺的语法糖(外观更好的代码),实际上并不等待任何东西

也许下面的代码可以清除这些内容:

var test=async()=>{
等待22;//即使价值是承诺也无所谓
console.log(“等待后”);
}
var结果=测试();

log(“外部测试我们不等待任何东西”,result)查看注释

@HMR-hm。。。我不明白-有问题的例子是异步的 函数someWrapper(),但该函数不返回任何内容(它 甚至没有返回声明(!)-你能解释一下你的想法吗 异步函数立即返回承诺的意思是
?-卡米尔·基尔切夫斯基

似乎您不理解异步等待。我通常建议人们停止工作,等待你明白承诺。然而,在下一个问题下的评论中,我给你答案:


someWrapper将立即返回一个承诺,该承诺将 未定义。wait仅在someWrapper函数中“waitis”,但
调用someWrapper的函数将立即收到一个承诺 解析为未定义。函数总是返回一些东西,如果您不这样做的话 在代码中,它将返回undefined。如果它是一个异步函数 如果没有回报,那么它将回报一个最终解决的承诺 未定义-HMR

wait是承诺的语法糖(外观更好的代码),实际上并不等待任何东西

也许下面的代码可以清除这些内容:

var test=async()=>{
等待22;//即使价值是承诺也无所谓
console.log(“等待后”);
}
var结果=测试();

log(“外部测试我们不等待任何东西”,result)
您的第一个测试使用
async
await
,它们按顺序运行承诺。第二个测试没有,所以每个承诺都会开始,然后按顺序完成。@Sidney你能详细说明一下吗?在我看来,我在someWrapper()中使用async/await,在Test2()中,我以同步(for循环)的方式调用这个函数。在第一个测试的循环中,
await
导致循环在
getSomePromise()处暂停
功能,直到承诺得到解决。在第二个测试中,没有一个
wait
,因此JavaScript在启动每个承诺后愉快地继续循环。如果不在函数中使用
wait
,使函数
async
实际上没有任何作用。@Sidney唯一的区别是我将循环体(在测试1中)移动到函数(测试2)。在我看来,这种行为是违反直觉的——你能同意吗?someWrapper会立即返回一个解析为未定义的承诺。wait仅在someWrapper函数中“waitis”,但函数