JavaScript库中的阻塞/非阻塞函数?
Posted
技术标签:
【中文标题】JavaScript库中的阻塞/非阻塞函数?【英文标题】:Blocking/non-blocking functions in JavaScript library? 【发布时间】:2020-03-29 23:50:04 【问题描述】:我正在移植一个库,其中包含需要能够在同步或异步模式下使用的 cpu 昂贵的函数。鉴于它们需要在节点和浏览器中工作,在当前 javascript(setTimeout、web-workers 等)中实现这些功能的最佳方法是什么?
【问题讨论】:
should I include two versions of each (sync and async)
如果合适的话 - Should I replace the callbacks with promises, or with async/await
就图书馆的消费者而言,技术上是一样的
如果您想要一个同步或异步运行的函数 - 该函数如何知道以哪种方式运行?
嗯,目前是根据是否提供回调
还不错 - 听起来不错
对,但是如果你尝试顺序调用一些这样的函数,你会在回调中的回调中得到一团糟
【参考方案1】:
每个函数我会有两个版本,并且让异步版本返回一个承诺而不是接受一个回调参数。
如何做到这一点取决于您。您可以从字面上返回一个承诺然后解决/拒绝它,或者您可以将函数标记为async
,这使它们隐式返回一个承诺,然后返回响应(这就像用一个值解析)。
class LibClass
a() // async a with promises returns Promise<ret>
return new Promise((resolve, reject) =>
setTimeout(() =>
const ret = doWork()
resolve(ret)
, 1)
)
a_sync() // sync a returns ret
const ret = doWork()
return ret
async b(data) // async function b returns Promise<ret>
const ret = doWork()
return ret
【讨论】:
【参考方案2】:这听起来你对同步和异步有点困惑。给定函数要么具有同步结果,要么具有异步结果。非此即彼。这个事实取决于函数的作用,而不是调用者的想法或想要的。
如果一个函数调用任何异步的或可能在其实现中调用任何异步的,那么它的最终结果是异步的,没有办法让它同步。它必须有一个异步接口。您不能提供同步接口,因为结果根本无法同步返回。
如果一个函数在其实现中没有调用任何异步的东西,那么它就是一个同步函数,你应该给它一个同步接口,因为它总是比异步接口更容易使用,并且同步接口也可以与其他异步代码一起使用所以它非常灵活。
因此,如果您有一个完全同步的库,您可以同时提供同步和异步接口,但没有理由这样做。只需提供一个同步接口,因为它总是更易于使用。
而且,库中执行任何异步操作的任何函数都必须具有异步接口。
因此,选择取决于您在库函数中所做的事情,而不是其他任何事情。
仅供参考,有时可能会有一个函数有时具有同步结果,有时具有异步结果。典型的例子是当一个值可能已经在本地缓存并立即可用,但如果不在缓存中,则必须从某个远程资源异步检索。在这种情况下,您提供了一个异步接口,即使结果立即可用,您仍然可以异步返回它。这样调用者就可以得到一个统一的接口,无论哪种方式都可以工作,调用者不必编写两种不同的方式来使用你的函数。注意:这应该是库设计中罕见的情况,而不是通常的情况。通常,一个函数要么一直是内部同步的,要么一直是异步的。
【讨论】:
【参考方案3】:你可以使用 async 关键字 喜欢:
class LibClass
async a()
return Promise.resolve('success');
【讨论】:
如果一个函数被标记为async
,它已经返回一个Promise。所以在你的例子中你可以return 'success'
。以上是关于JavaScript库中的阻塞/非阻塞函数?的主要内容,如果未能解决你的问题,请参考以下文章