【问题标题】:Are async functions just for IO blocking operations?异步功能是否仅用于 IO 阻塞操作?
【发布时间】:2018-09-04 00:56:27
【问题描述】:

我有一些函数可以对数据和数组进行大量计算,但都在内存中,它不做任何 IO。我一直在阅读尝试进入 nodejs,我想知道进行 then 异步是否有任何好处?比如函数a

function a(b, c, d) {
  // a lot of operations with arrays
  return value;
}

如果不涉及任何 IO 阻塞操作,在这种情况下返回 Promise 是否有意义?例如:

function a(b, c, d) {
  return new Promise(resolve, reject) {
    // a lot of operations with arrays
    resolve(value);
  }
}

在这种情况下使用 Promise 是否有任何改进,或者我只是过于复杂了,应该只返回值而不是 Promise?

【问题讨论】:

  • 传递给 Promise 构造函数的执行器是同步执行的 - 所以,没有任何好处(不过,奇怪的是,我看到一些代码运行速度快了 10 倍 - 至少在 Firefox 中,所以我猜不是那么相关- 在执行器内部) - 注意:您发布的 Promise 代码无效
  • 也许这个帖子可以帮到你:stackoverflow.com/questions/43482775/…
  • 话虽如此,您可以为// a lot of operations with arrays 编写代码,使其不会“阻塞” - 即通过在受控中执行小批量操作,使其成为伪异步setTimeout/setImmediate/任何可用的序列 - 在这种情况下,Promise 可能是有益的。这实际上取决于“操作”是什么,以及为什么您希望它们“非阻塞”-(这是某种服务器的一部分,并且在执行密集计算时它停止响应客户端请求?)
  • @JaromandaX 是的,在给出响应之前它们是服务器进程的一部分,此时我没有遇到任何性能问题,但我担心在某个时候有更多请求我会开始有问题。
  • 查看我的答案 - 显然我无法帮助您“拆分”并执行“数组上的一些操作”,因为您没有显示有关“数组的大量操作”的任何细节" - 但希望这能让您了解可以做什么

标签: javascript node.js promise async-await es6-promise


【解决方案1】:

不,异步函数只是 Promise 之上的语法糖。如果你的函数实际上没有任何异步操作(比如网络请求),它会一直保持同步执行并同步解析,所以它和普通函数没有什么不同。

Javascript 是单线程的。

【讨论】:

  • 这只有 99% 是正确的。所有.then() 处理程序都是异步执行的,因此将一堆同步代码放入async 函数或返回promise 的常规函数​​将立即解决promise,但不会同步调用.then() 处理程序——它们仍然会在未来的滴答声中被调用。在任何情况下,都不应该将async 函数用于完全同步的代码。
  • 我知道使用了“异步”这个词并且问题标记为async-await - 但这个问题实际上与async-await 无关,OP 甚至不使用@987654327代码中的@或await关键字!!不知道这怎么可能回答这个问题:p
  • @JaromandaX 我使用async - await 在另一个函数中调用这个函数。除非在其他方向有另一个答案,否则这个答案确实解决了我的问题,因为现在我知道我没有从返回承诺而不是返回值中获得任何好处。
【解决方案2】:

您可以在“批处理”中执行 lot of operations with arrays 以避免“阻塞”其他执行 - 以下是“伪”代码,因为您没有显示 // a lot of operations with arrays 实际上是什么......所以

function a(b, c, d) {
    return new Promise((resolve, reject) => {
        function processBatch() {
            // do some operations with arrays
            if (error) {
                reject(error);
            } else if (needToProcessMore) {
                setImmediate(processBatch);
            } else {
                resolve(someResult);
            }
        }
        setImmediate(processBatch);
    });
}

另外,(虽然我自己从未使用过它们)有可用于节点的“线程”和“线程工作者”类型库

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-16
    相关资源
    最近更新 更多