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

时间:2017-05-20 19:48:57

标签: javascript node.js async-await

尝试在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)
    }
}

2 个答案:

答案 0 :(得分:10)

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

以下示例将在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();




没有async / await,输出如下:

hi
hello

以下是没有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();




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

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

hello
hi

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

答案 1 :(得分:4)

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

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

对于数组,您需要将其映射到promises数组,然后使用Promise.all将其转换为“数组的承诺”,例如:

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