在异步函数中等待新的 Promise

维图斯·德·图利奥

我有一个基于异步的代码库,我需要与一些“基于回调”的外部库进行交互。我虽然可以用一个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));
}

我的疑问是

  • 应该myWrapper await承诺吗?还是应该return立即?
  • 如果没有await,是否应该将此功能标记为async
  • 写这些await new Promise(...)东西有什么惩罚吗?
TJ克劳德

应该myWrapper await承诺吗?还是应该立即归还?

随你(由你决定。不需要在函数return await的顶层执行,¹但通过将函数包含在异步堆栈跟踪中可能会使异步堆栈跟踪更清晰。所以你可能会因为这个原因保留它,或者你可能会因为这个原因删除它。:-) (我应该注意到,在最新的 V8 中,我无法再看到堆栈跟踪的差异,两者都包括包装函数。所以这方面的事情可能已经发生了变化;我知道异步堆栈跟踪是一个热门开发一段时间。)asyncasync

如果没有await,是否应该将此功能标记为async

不,如果您删除await,则没有理由将async.

写这个等待新的 Promise(...) 东西有什么惩罚吗?

如果您特别指的是awaitin return await,那么不,不是当您使用的承诺await是本机承诺时。它曾经在函数承诺的解决中引入(基本上无害的)异步滴答async,但规范已更新以允许引擎避免它。


¹如果你想在函数中捕获对 promise 的拒绝,或者你想在子句中做某事,或者类似的事情——函数逻辑依赖于该 promise 的任何事情,使用return await notasync在函数的顶层必要的在函数本身返回之前解决。例如,您在这里需要它:finallyasyncasync

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.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章