web-dev-qa-db-ja.com

JavaScriptエンジンは、内部でどのようにasync / awaitをpromiseに変換しますか?

Async/await構文がPromisesに変換される方法に興味があります。多分私はそれについて適切に考えていないだけかもしれませんが、このコードがどのようにPromiseに変換されるのかわかりません:

async function myFunc(doAwait) {
    doSomething();
    if (doAwait) {
        await doSomethingAsync();
    }

    return doSomethingElse();
}

doAwaitfalseの場合、この関数は次と同等に実行されると思います。

return new Promise(res => {
    doSomething();
    res(doSomethingElse());
});

trueの場合、次のようになります。

return new Promise(() => { doSomething(); })
    .then(() => doSomethingAsync())
    .then(() => doSomethingElse());

次のようなことができます:

let p = new Promise(() => { doSomething(); });
if (doAwait) {
    p = p.then(() => doSomethingAsync());
}
return p.then(() => doSomethingElse());

しかし、それは余分な、おそらく不要なthenを導入します。たぶんそれは避けられないことです。

1
dx_over_dt

この async/awaitコード:

async function myFunc(doAwait) {
    doSomething();
    if (doAwait) {
        await doSomethingAsync();
    }

    return doSomethingElse();
}

基本的にこれと同等です:

function myFunc(doAwait) {
    doSomething();
    if (doAwait) {
        return Promise.resolve(doSomethingAsync()).then(doSomethingElse);
    }

    return Promise.resolve(doSomethingElse());
}

関数呼び出しの同期例外を含む完全な同等性については、次のようになります。

function myFunc(doAwait) {
    try {
        doSomething();
        if (doAwait) {
            return Promise.resolve(doSomethingAsync()).then(doSomethingElse);
        }

        return Promise.resolve(doSomethingElse());
    } catch(e) {
        return Promise.reject(e);
    }
}
3
jfriend00