在大量使用 Node 之后,我不得不习惯以非阻塞方式编写代码,但是我可以做到这一点的主要方法是使用本身异步的函数。例如:stat(f,callback)
或forEach(array,callback)
它们会自动从我认为是主要执行高速公路的地方获取您给它们的任何回调并在接到电话后立即返回。
我想知道的是:如何告诉 ECMA 引擎异步执行一个函数,无论它是什么?
我的特殊用例涉及在 DOM childList 上迭代 for 循环来解析数千个元素;我的问题是每个其他元素都是一个我想跳过的文本 Node 。虽然我会使用 forEach()
这不是最好的,我只看到 for(a,i=0;a=table[i];i=i+2){/*process 'a'*/}
能够纠正这个问题,但代价是被阻塞。最好的行动方案是什么?
额外问题:在 JS 必须执行繁重工作的用例中,NodeJS 的编码实践在客户端应用程序中是否站得住脚?
最佳答案
注意:Array.prototype.forEach
是同步的,而不是异步的。 JS 标准 ( ECMAScript 5th edition ) 中定义的任何内容都不能是异步的,因为该标准没有定义异步语义(Node.js 和 DOM 定义了)。
您可以使用setTimeout
(适用于浏览器和 Node.js)或 process.nextTick
(特定于 Node.js):
for (...) {
doWorkAsync(...);
}
function doWorkAsync(...) {
setTimeout(doWorkSync.bind(null, ...), 0);
}
function doWorkSync(...) {
...
}
如果您选择利用闭包,那么在使用自由变量时要小心,因为当最终调用回调时,变量可能会发生变化。
使用异步框架,例如 Q by kriskowal (可跨 Node.js 和现代浏览器移植),您可以进行 MapReduce 风格的编程:
var Q = require('q'); // npm package 'q'
function getWorkloads() {
var workloads = [ ];
for (...) {
workloads.push(Q.fcall(doWorkSync.bind(null, ...)));
}
return workloads;
}
Q.all(getWorkloads()).then(function (results) {
// results array corresponds to
// the array returned by getWorkloads.
});
关于javascript - 有没有办法使代码块本身不阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10775935/