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库中的阻塞/非阻塞函数?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 默认是同步(阻塞)还是异步(非阻塞)

如何制作非阻塞的javascript代码?

如何制作非阻塞的javascript代码?

python 怎么启动一个外部命令程序,并且不阻塞当前进程

为啥C没有像javascript中的setTimeout这样的非阻塞睡眠功能

现代浏览器中的非阻塞 javascript 和 css。还需要吗?