假设您需要执行一些依赖于某些临时文件的操作。既然我们在这里谈论Node,那么这些操作显然是异步的。为了知道何时可以删除临时文件,等待所有操作完成的惯用方式是什么?
这是一些代码,显示我想做什么:
do_something(tmp_file_name, function(err) {});
do_something_other(tmp_file_name, function(err) {});
fs.unlink(tmp_file_name);
但是,如果我这样编写,则可以在前两个调用有机会使用该文件之前执行第三个调用。我需要某种方法来确保前两个调用在结束之前已经完成(调用了它们的回调),而没有嵌套这些调用(并使它们在实践中保持同步)。
我考虑过在回调上使用事件发射器,并将计数器注册为接收器。计数器将接收已完成的事件并计算仍有多少操作待处理。当最后一个完成时,它将删除该文件。但是存在比赛条件的风险,我不确定这通常是如何完成的。
Node人员如何解决此类问题?
更新:
现在,我建议看一下:
Promise对象用于延迟和异步计算。Promise表示尚未完成的操作,但有望在将来进行。
一个流行的承诺库是蓝鸟。A建议看看为什么答应。
您应该使用promise来解决这个问题:
> > fs.readFile("file.json", function (err, val) {
> if (err) {
> console.error("unable to read file");
> }
> else {
> try {
> val = JSON.parse(val);
> console.log(val.success);
> }
> catch (e) {
> console.error("invalid json in file");
> }
> }
> });
变成这个:
> > fs.readFileAsync("file.json").then(JSON.parse).then(function (val)
> {
> console.log(val.success);
> })
> .catch(SyntaxError, function (e) {
> console.error("invalid json in file");
> })
> .catch(function (e) {
> console.error("unable to read file");
> });
使用Promise,基于Node.js和浏览器的基于生成器的控制流优势,可让您以一种不错的方式编写非阻塞代码。
> > var co = require('co');
>
> co(function *(){
> // yield any promise
> var result = yield Promise.resolve(true);
> }).catch(onerror);
>
> co(function *(){
> // resolve multiple promises in parallel
> var a = Promise.resolve(1);
> var b = Promise.resolve(2);
> var c = Promise.resolve(3);
> var res = yield [a, b, c];
> console.log(res);
> // => [1, 2, 3]
> }).catch(onerror);
>
> // errors can be try/catched
> co(function *(){
> try {
> yield Promise.reject(new Error('boom'));
> } catch (err) {
> console.error(err.message); // "boom"
> }
> }).catch(onerror);
>
> function onerror(err) {
> // log any uncaught errors
> // co will not throw any errors you do not handle!!!
> // HANDLE ALL YOUR ERRORS!!!
> console.error(err.stack);
> }
如果我理解正确,我想您应该看一下非常好的异步库。您应该特别看一下该系列。只是来自github页面的摘录的一个副本:
async.series([
function(callback){
// do some stuff ...
callback(null, 'one');
},
function(callback){
// do some more stuff ...
callback(null, 'two');
},
],
// optional callback
function(err, results){
// results is now equal to ['one', 'two']
});
// an example using an object instead of an array
async.series({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function(){
callback(null, 2);
}, 100);
},
},
function(err, results) {
// results is now equals to: {one: 1, two: 2}
});
另外,该库还可以在浏览器中运行。
问题内容: 我有一个循环,可以调用API并将结果编译成数组。我如何等待所有调用完成后才能恢复执行?我看到了一系列有关如何等到打完一个电话的答案,但我不知道如何检查所有这些。如果我做一个while循环,一直等到’obj’是正确的长度,则页面只会停顿直到调用完成,这不是我想要的。请帮助? 问题答案: 如果您使用jQuery的deferred,这很容易。有一种方法,等待多个诺言完成,然后运行回调。那就是
问题内容: 我有这样的代码: 我的问题是,节点在运行时立即终止。它显示“ Icanhasclient”,但没有调用回调内的console.log。 (本例中的mysql是node- mysql 。 有什么办法可以使node.js在退出之前等待回调完成? 问题答案: 回调未排队 节点运行直到所有事件 队列 都为空。诸如以下的调用时,回调将添加到事件 队列 中 已执行。该调用是模块开发人员编写的代码的
问题内容: 我有一个在另一个类中启动异步任务,然后应该等待结果。 问题是方法将在方法运行完成后立即完成,对吗? 这意味着,通常,在启动异步任务后,它将立即关闭,并且不再在那里接收结果。 如何使以上代码段正常工作?开始任务后,我已经尝试放入(任意持续时间)。似乎可以正常工作。 但这绝对不是一个干净的解决方案。也许甚至有一些严重的问题。 有更好的解决方案吗? 问题答案: 使用标准类代替,从回调启动异步
问题内容: 我已经审查了很多有关此类问题的答案,但现在我对最佳方法感到困惑。鉴于最新的jquery,我想 调用一个ajax函数 做ajax处理(成功或错误)//正常工作 成功或错误时,将状态返回到调用函数以进行进一步处理 在调用函数(doAjax)中,如何等待回调,然后完成对成功或错误的处理(在这种情况下,成功时清除表格,错误时保持原样) 感谢任何建议, Art [EDIT] 你们发现有一个错字,
问题内容: 当使用简单的回调(例如下面的示例)时: 如何更改功能以使用异步/等待?具体来说,假设“ someEvent”被保证只能被调用一次,那么我希望函数测试是一个异步函数,该异步函数在执行回调之前不会返回,例如: 问题答案: 不是魔术。异步函数是可以为您解开Promises的函数,因此您需要返回一个Promise才能起作用。像这样: 然后 但这也是一个谎言,因为异步函数也返回Promises本
使用以下示例中的简单回调时: 如何将函数更改为使用异步/等待?具体地说,假设某个事件保证被调用一次并且只有一次,我希望函数测试是一个异步函数,直到执行回调才返回,例如: