在异步函数中等待新的 Promise

await a new Promise in an async function

我有一个基于异步的代码库,我需要与一些“基于回调”的外部库进行交互。 我虽然可以用 Promise 包装外部库,它可以充当“桥梁”并为我提供异步外观。 我最终对如何定义这个包装器产生了疑问。 在代码中:

export function externalApi(onsuccess: (response: string) => void): void {
    // stuff
    onsuccess('response');
}

export async function myWrapper(): Promise<string> {
    return await new Promise((resolve) => externalApi(resolve));
}

我的疑惑是

should myWrapper await the promise? or should it return it immediatly?

这取决于你。在 async 函数的顶层执行 return await 不是必需的,¹ 但 可能 通过包含 async 函数使异步堆栈跟踪更清晰在异步堆栈跟踪中。所以你可能会因为那个原因保留它,或者你可能会因为那个原因删除它。 :-)(我应该注意到,在最新的 V8 中,我再也看不到堆栈跟踪中的差异,两者都包含包装函数。所以事情可能在这方面有所进展;我知道异步堆栈跟踪是一个热门开发一段时间的区域。)

if there is no await, should this function be marked as async?

不,如果 你删除了 await,它没有理由成为 async

are there some penalties writing this await new Promise(...) stuff?

如果您具体指的是 return await 中的 await,那么不,当您使用 await 的 promise 是本机 promise 时,则不会。它过去常常在 async 函数的承诺中引入一个(基本上无害的)异步滴答,但规范已更新以允许引擎避免它。


¹ 在 async 函数的顶层使用 return await not is 如果你想捕捉函数中对 promise 的拒绝,或者你想在 finally 子句中做某事,或类似的东西——任何 async 函数的逻辑依赖于在 async 函数本身 returns。例如,您在这里需要它:

async function example() {
    try {
        return await somethingThatProvidesAPromise();
    } catch (e) {
        throw new WrapperError(e);
    }
}

这里

async function example() {
    const lock = acquireLock();
    try {
        return await doSomethingWith(lock);
    } finally {
        releaseLock(lock); // (Where `releaseLock` guarantees it nevers throws)
    }
}

如果没有 await.

,这些都不正确