循环中的节点 Grunt 异步任务,闭包不起作用
Posted
技术标签:
【中文标题】循环中的节点 Grunt 异步任务,闭包不起作用【英文标题】:Node Grunt Asynchronous Task in Loop with Closure not Working 【发布时间】:2013-01-02 16:38:33 【问题描述】:提前感谢您查看此内容。
我在一个不工作的循环中有一个异步任务。我已经确保:
-
将我的循环变量“key”包装在一个闭包中以避免经典的“最后一个值”
only”问题,其中循环在异步任务返回值之前很久就完成了,并且只显示最后一个值。
调用 done(error) 以完成我的异步任务(根据 Gruntjs 常见问题解答)
使用 hasOwnProperty() 确保键是对象的实际属性,而不是来自原型。
遵循 node.exec 示例的格式,除了将 exec 的值分配给一个变量——我已经尝试过,但没有帮助。请参阅下面的第一个参考。
这个函数输出......什么都没有!?由于某种原因, grunt.log.writeln 语句甚至没有触发。任务完成没有错误。我还尝试添加 20 秒的延迟,以防脚本在异步任务返回之前完成。奇怪的是,如果我不调用“done(error)”,文件会被写入文件(当我用 grunt.file.write 语句替换 writeln 时)。
var done = this.async(),
exec = require('child_process').exec,
myJSON =
"file1" : "C:/home/me/jquery.js",
"file2 " : "C:/home/me/grunt.js",
...
"fileN" : "C:/home/me/N.js"
,
count;
for (var key in myJSON)
if (myJSON.hasOwnProperty(key))
(function (key)
exec( 'type "' + myJSON[key] + '"',
function(error, stdout, stderr)
if (error)
grunt.log.writeln('!!! exec error: ' + error);
grunt.log.writeln('stdout: ' + stdout);
grunt.log.writeln('stderr: ' + stderr);
done(error);
);
)(key);
count++;
参考资料:
http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback https://github.com/gruntjs/grunt/wiki/Frequently-Asked-Questions
【问题讨论】:
【参考方案1】:done()
应该只在整个操作完成时调用,这意味着当所有exec()
方法都运行了它们的回调时。目前,您正在每次迭代中执行 done
回调。您可以通过使用 grunt 附带的节点模块 async 中的 forEach
方法轻松实现此目的(grunt.util.async
(,如果您希望按顺序执行 exec()
方法,则为 forEachSeries
。
类似这样的东西(未测试):
var done = this.async();
var exec = require('child_process').exec;
var async = grunt.util.async; // updated
var myJSON =
"file1": "C:/home/me/jquery.js",
"file2": "C:/home/me/grunt.js",
...
"fileN": "C:/home/me/N.js"
;
async.forEach(Object.keys(myJSON), function(el, cb)
exec('type "' + myJSON[el] + '"', function(error, stdout, stderr)
if (error)
grunt.warn('!!! exec error: ' + error)
return cb(error);
grunt.log.writeln('stdout: ' + stdout);
grunt.log.writeln('stderr: ' + stderr);
cb();
);
, function(error)
done(!error);
);
【讨论】:
tyvm。常见问题解答让我相信 done() 必须为任务中的每个异步操作调用。这是一个很大的帮助。我很感激你的时间。 :)。 所以,这里的要点是 grunt.utils.async 实用程序更适合处理异步任务——而不是手动创建闭包等,对吗? 这是正确的,但不仅仅是咕噜声。一般来说,在 Node.js 中工作时,它是无价的。 github.com/caolan/async @SindreSorhus 对您调用 grunt.task.run('asynctaskname:asynctarget') 而不是 exec() 的实例有任何建议吗?在这种情况下,存在一种异步冲突,因为循环产生了一堆异步任务 - 并且任务的异步“完成”没有连接到 async.forEach grunt.util.async 现已弃用,但可以替换为npmjs.com/package/async以上是关于循环中的节点 Grunt 异步任务,闭包不起作用的主要内容,如果未能解决你的问题,请参考以下文章