在大量使用node之后,我不得不习惯于以非阻塞的方式编写代码,但是主要的方法是使用本身是异步的函数。例如:stat(f,callback)
或forEach(array, callback)
它们会自动从我认为是主要执行通道的地方获取您给它们的任何回调,并在被调用后立即返回。
我想知道的是:如何告诉ecma引擎无论它是什么都可以异步执行函数?
我的特定用例涉及到在dom子列表上迭代for循环来解析数千个元素;我的问题是,每个其他元素都是一个文本节点,我想跳过它。虽然我会使用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 do)。
您可以使用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.
});