在我的节点应用程序中,我需要生成多个文件写入并等待它们完成,然后才能继续执行其他操作。我通过以下方式实现了这一目标:
let counter = 0;
(some loop declaration) {
// (preparing data etc)
counter += 1;
fs.writeFile(fname, fdata, (err) => {
counter -= 1;
});
}
let waitForCallbacks = function() {
if (fcounter > 0) {
setTimeout(waitForCallbacks, 0);
}
};
waitForCallbacks();
虽然它按预期工作,但我觉得可能会有更好的成语。有什么建议吗?
答案 0 :(得分:4)
虽然它按预期工作,但我觉得可能会有更好的成语。
这是承诺的目的之一。这里的代码是用promises重写的(它可以更进一步,有一些libs可以承诺 - 如果是NodeJS API):
let operations = []
(some loop declaration) {
// (preparing data etc)
operations.push(new Promise((resolve, reject) => {
fs.writeFile(fname, fdata, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
}));
}
Promise.all(operations).then(() => {
// All done
});
或者考虑我们是否有writeFile
的承诺版本:
let operations = []
(some loop declaration) {
// (preparing data etc)
operations.push(writeFileWithPromise(fname, fdata));
}
Promise.all(operations).then(() => {
// All done
});
或者如果"循环"是一个可迭代的,我们可以变成一个数组并使用map
on:
Promise.all(
Array.from(theThingy).map(entry => writeFileWithPromise(entry.fname, entry.fdata))
).then(() => {
// All done
});
答案 1 :(得分:2)
承诺是一种方式。但是,如果您不喜欢它们,可以使用名为async的知名库。
以下是您可以对案件采取的措施。以下是使用并行处理的初步方式:
async.parallel([
function(done) {
fs.writeFile(fname1, fdata1, (err) => {
done(err, customResults1);
});
},
function(done) {
fs.writeFile(fname2, fdata2, (err) => {
done(err, customResults2);
});
}
],
// The callback when every function above is done
function(err, results) {
// `results` contains a collection of what you've passed
// on the `done` callbacks above
});
更具体地说明您的用例,它看起来像:
async.parallel(
['file1', 'file2'].map(function(fname) {
return function(done) {
fs.writeFile(fname, fdata, (err) => {
done(err, customResults);
});
};
}),
// The callback when every function above is done
function(err, results) {
// `results` contains a collection of what you've passed
// on the `done` callbacks above
}
);
如果您希望逐个运行任务,则可以使用async.series。如果您希望函数将其结果传递给下一个任务,则可以使用async.waterfall。当然,您可以使用其他功能,但我提到的功能是一些非常常见的功能。
答案 2 :(得分:-1)
使用Async:
async.map([['name1', 'data1'], ['name2', 'data2'], ['name3', 'data3']],
function (item, cb) {
fs.writeFile(item[0], item[1], (err, res) => {
callback(err, res);
});
},
function(err, results) {
// results is now an array of results
});
答案 3 :(得分:-1)
我已经尝试过Promises,我并不完全相信使用它们做这样的事情有很多好处:
let counter = 0;
(some loop declaration) {
// (preparing data etc)
counter += 1;
fs.writeFile(fname, fdata, (err) => {
counter -= 1;
if ( counter==0 ) done()
});
}
function done(){
// that's it
}
与初始代码非常相似,除了使用setTimeout(),我会在每个操作完成时检查计数器的值。
IMO,这同样有效,也许更容易阅读。
或者,如果您不想要单独的功能来完成......
let counter = 0;
(some loop declaration) {
// (preparing data etc)
counter += 1;
fs.writeFile(fname, fdata, (err) => {
counter -= 1;
if ( counter==0 ) {
// that's it, finish up
}
});
}