Javascript 在 Node 中处理嵌套异步等待调用的正确方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44090197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:20:10  来源:igfitidea点击:

What is the correct way to handle nested async await calls in Node?

javascriptnode.jsasync-await

提问by user3162553

Trying to learn the async pattern in Javascript but it doesn't appear that it waits for the following line. In the following example, the collection is the request object and not the actual parsed body. Isn't awaitsupposed to wait for the request to finish?

尝试学习 Javascript 中的异步模式,但它似乎没有等待以下行。在以下示例中,集合是请求对象,而不是实际解析的正文。不await应该等待请求完成吗?

async function importUsers(endpoint) {
    const options = {
        data: search,
        uri: endpointCollection,
        headers,
    }

    try {
        const collection = await browser.post(options, (err, res, body) => JSON.parse(body))
        // collection is the request object instead of the result of the request
        const users = await collection.data.forEach(item => parseUserProfile(item));

        await users.forEach(user => saveUserInfo(user))
    } catch(err) {
        handleError(err)
    }
}



async function parseUserProfile({ username, userid }) {
    const url = userProfileString(username)

    try {
        const profile = await browser.get(url, headers, (err, res, body) => {   
            return { ... } // data from the body
        })
    } catch(err) {
        handleError(err)
    }
}

回答by Get Off My Lawn

Async/Await only works on functions that return (and resolve) a promise.

Async/Await 仅适用于返回(并解析)promise 的函数。

The following example will write to the console after 3 seconds, and then continue on.

以下示例将在 3 秒后写入控制台,然后继续。

// Tell the browser that this function is asynchronous
async function myFunc() {
    // Await for the promise to resolve
    await new Promise((resolve) => {
        setTimeout(() => {
            // Resolve the promise
            resolve(console.log('hello'));
        }, 3000);
    });
    // Once the promise gets resolved continue on
    console.log('hi');
}

// Call the function
myFunc();

Without async/await, the output would be as follows:

如果没有 async/await,输出将如下所示:

hi
hello

Here is an example without async/await:

这是一个没有 async/await 的例子:

// Tell the browser that this function is asynchronous
async function myFunc() {
    // Skip await
    new Promise((resolve) => {
        setTimeout(() => {
            // Resolve the promise
            resolve(console.log('hello'));
        }, 3000);
    });
    // Since await was not used, this will print first
    console.log('hi');
}

// Call the function
myFunc();

This would be because the hioutput would run and then after 3 seconds the timeout would run.

这是因为hi输出将运行,然后在 3 秒后超时将运行。

But with async/await, the output looks like this:

但是使用 async/await,输出如下所示:

hello
hi

This is because we await for the timeout then we run the hioutput.

这是因为我们等待超时然后运行hi输出。

回答by Sheng

awaitshould expect a promise, for a callback style async function, you can transform it like:

await应该期待一个承诺,对于回调样式的异步函数,您可以将其转换为:

new Promise((resolve, reject) => browser.post(options, (err, res, body) => resolve(JSON.parse(body))))

For an array, you need to map it to an array of promises, then use Promise.allto turn it to a 'promise of array', for example:

对于一个数组,你需要将它映射到一个promise数组,然后使用Promise.all将它变成一个'promise of array',例如:

Promise.all(collection.data.map(item => parseUserProfile(item)))