Node.js Array.map() 是异步的吗?

Posted

技术标签:

【中文标题】Node.js Array.map() 是异步的吗?【英文标题】:Is Node.js Array.map() asynchronous? 【发布时间】:2012-09-27 15:13:54 【问题描述】:

我可以指望每次调用 doSomething() 时都完成 nodeIDs 映射吗?

nodeIDs = $.map(nodeIDs, function(n)
    return n.match(/\d+$/);
);
doSomething(nodeIDs);

我认为 node.js 中的所有回调都是异步的?我确实读过一篇关于一般编程的文章,回调可能是同步的,但我不确定 node.js?

【问题讨论】:

这里的$是什么? map 接受一个回调函数来应用于列表的每个成员,而不是在完成迭代完成时的回调。 谢谢乔维。至于 $,我只是在试验 node-jquery 模块,并没有费心去编辑它。 【参考方案1】:

javascript 也是一种函数式编程语言。你这里有一个“高阶函数”,一个将函数作为参数的函数。高阶函数是同步的(但请参见下面的注释)。

来源:

Functional Programming Higher order functions in JavaScript

map() 是高阶函数的典型例子。它接受一个函数并将其应用于数组的所有元素。这个定义听起来很“实用”。 Node 也不提供此功能。它由MDN Array.prototype.map() 记录并由ECMAScript 5.1 指定。

回答您的问题:是的,doSomething(nodeIDs) 在应用所有元素之后被调用。


注意:高阶函数是函数式编程的一个概念。 JavaScript 是功能性的,但也深深植根于在浏览器或服务器上执行代码的实用性。我会说,例如setTimeout() 不是一个高阶函数,即使它需要一个函数作为参数,因为setTimeout() 并不是真正纯粹的函数,因为它使用时间。纯粹的功能是永恒的。例如map() 的结果不依赖于时间。这就是这个问题的真正意义所在。如果某些事情不依赖于时间,您可以同步执行它。问题解决了。

感谢 Simon 挑战 JavaScript 中高阶函数的定义。

【讨论】:

谢谢 nalply。查看 map() 的参考实现会有所帮助。 高阶函数是同步的——真的吗? setTimeout 也是高阶函数,但它是异步的。 @SimonA.Eugster 你说得有道理。如果您将函数作为参数严格定义为“高阶”,那么异步函数也是“高阶”。以函数为参数的同步函数叫什么? @nalply 我们从来没有在函数式​​编程中研究过异步,这里不能用一个术语。我什至不确定函数是否异步在函数式编程的概念中是否重要。想知道专家会回答什么:)【参考方案2】:

是的,.map 是同步的。 “回调”并不意味着“异步”。

【讨论】:

谢谢 Charmander。我的意思是说'如果有疑问,假设回调可以在不同的时间异步调用'。所以真正的问题是(见上面我的 cmets) - 通常我如何判断给定的库函数是否是异步的? 例如 node.js 文件函数有很好的文档记录,但其他的,比如数组映射,我似乎找不到这条特定的信息。 那是因为它们不是 Node 提供的。它们属于 V8 运行时。 V8 实现了 ECMAScript。 Array.map() 记录在这里:developer.mozilla.org/en-US/docs/JavaScript/Reference/…。【参考方案3】:

导入async 模块以具有异步“map”方法

var async = require('async');

var arr = ['1','2'];
async.map(arr, getInfo, function (e, r) 
  console.log(r);
);

function getInfo(name, callback) 
  setTimeout(function() 
    callback(null, name + 'new');
  , 1000);

【讨论】:

【参考方案4】:

此函数是同步的 - 否则无法返回映射操作的结果。

任何可能需要较长时间的回调(主要是由于 IO)在 nodejs 中都是异步的 - 除非该方法被明确标记为同步(例如 fs.readFileSync - 但不使用回调)。您可能以某种方式混淆了这一点。

【讨论】:

感谢小偷大师。我了解 IO 功能的 Sync 和 Async 版本的一部分,并且过去都使用过。更好地重新表述我的问题:给定一段代码,当没有回调时,我可以假设同步流。但是当有回调时,有没有明显的方法来确认单向或其他?如果涉及 IO,它们可能是异步的。但在 map() 的情况下,我不太确定——nodejs 和 Javascript 引用似乎都没有指定这一点。那么如何判断我遇到的下一个库函数呢? 文档说明了这一点。例如。 nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback"异步重命名"【参考方案5】:

使用forof(同步):

let arr = ['fizz', 'buzz']
//example
    for (const item of arr) 
   //this Examp_func returns array
     console.log((await Examp_func(item )).length);
    

【讨论】:

【参考方案6】:

有一个有用的库awaiting。 map 会帮助你。

【讨论】:

【参考方案7】:

是的,map 函数是异步的,是ECMAScript 的一部分。 NodeJS 使用该定义中的 map。 尝试运行此代码以查看它的实际效果。

const array = ['first','second']

function name(params) 
  setTimeout(
    () => console.log('name: ' + params),
    5000
  );


console.log('wait for 5 seconds')
array.map(v => 
  name(v)
)

【讨论】:

以上是关于Node.js Array.map() 是异步的吗?的主要内容,如果未能解决你的问题,请参考以下文章

Array.map() 的异步回调

node.js里的forEach也是异步的吗

Node.js 承诺、异步或只是回调

所有 Redis 命令都是异步的吗?

关于node.js内部异步I/O机制的困惑

在Array#map()中异步/等待