2016-04-15 163 views
0

我有,我正在写东西文件:的NodeJS:如何等待几个异步任务完成

var stream = fs.createWriteStream("my_file.txt"); 
stream.once('open', function(fd) { 
    names.forEach(function(name){ 
    doSomething(name); 
    }); 
    stream.end(); 
}); 

这是工作确定,我能够写入文件。 问题是doSomething()函数有一些异步的部分。可以使用dnsLookup函数给出一个示例。某处在我的DoSomething的(),我有:

dns.lookup(domain, (err, addresses, family) => { 
    if(err){ 
    stream.write("Error:", err); 
    }else{ 
    stream.write(addresses); 
    } 
}); 

现在,我的问题是,由于DNS检查是异步的,代码保持执行关闭流。当DNS响应终于到来时,它无法写入任何地方。 我已经尝试使用异步模块,但它不起作用。可能我做错了什么。

有什么想法?

+0

承诺存在解决您遇到的问题。我会看看类似https://github.com/kriszyp/promised-io – inkdeep

+0

附注:我相当肯定你的意思是'if(err)'而不是'if(!err)',因为连接到它的块用于处理错误。 –

回答

2

现在是的NodeJS大多了ES2015功能,加快(我注意到你正在使用至少一个箭头的功能),你可以在JavaScript中使用本地的承诺(以前你可以使用库):

var stream = fs.createWriteStream("my_file.txt"); 
stream.once('open', function(fd) { 
    Promise.all(names.map(name => doSomething(name))) 
    .then(() => { 
    // success handling 
    stream.end(); 
    }) 
    .catch(() => { 
    // error handling 
    stream.end(); 
    }); 
}); 

(行Promise.all(names.map(name => doSomething(name)))可以简单地Promise.all(names.map(doSomething))如果你知道doSomething忽略额外的参数和仅使用前)。

Promise.allspec | MDN)接受一个迭代器并返回一个承诺,当迭代器中的所有承诺都被解决时(非承诺值被视为使用该值作为解决方案的已解决承诺)。

其中doSomething变为:

function doSomething(name) { 
    return new Promise((resolve, reject) => { 
    dns.lookup(domain, (err, addresses, family) => { 
     if(!err){       // <== You meant `if (err)` here, right? 
     stream.write("Error:", err); 
     reject(/*...reason...*/); 
     }else{ 
     stream.write(addresses); 
     resolve(/*...possibly include addresses*/); 
    }); 
    }); 
}); 

有各种库即会“的承诺,IFY”节点式的回调,那么你使用的承诺是比上面的搭配不太笨重;在这种情况下,您可以直接使用来自承诺dns.lookup的承诺,而不是自行创建额外的承诺。

+0

这个完美的工作!谢谢 – Nahoot