web-dev-qa-db-ja.com

Nodeでネストされた非同期待機呼び出しを処理する正しい方法は何ですか?

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)
    }
}
14
user3162553

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出力を実行するためです。

10
Get Off My Lawn

awaitはpromiseを予期する必要があります。コールバックスタイルの非同期関数の場合、次のように変換できます。

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

配列の場合、Promiseの配列にマッピングする必要があります。次に、Promise.allを使用して、「Promiseの配列」に変換する必要があります。次に例を示します。

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