我尝试使用节点js复制多个文件。
以下是我尝试做的一个例子:
var request = require('request');
va photos [{ 'url': 'http://xxxx.com/im1', 'name' : 'name1' }, { 'url': 'http://xxxx.com/im12', 'name' : 'name2' },
for (var i = 0; i < photos.length; i++) {
request(photos[i].source).pipe(fs.createWriteStream(photos[i].name));
}
在1000次通话后,我有一个套接字挂出错误。
根据@Timothy Strimple的建议,我决定使用异步模块。
我的代码现在是这样的:
async.whilst(function () { return !stop; },
function (callback) {
console.log("get next 20 image");
JM.api('/' + album.id + '/photos', { after: next }, function (resf) {
if (!resf || resf.error) {
console.log(!resf ? 'error occurred' : resf.error);
}
console.log("albums" + album.id + " " + resf.data.length + " dir" + dir);
async.eachSeries(resf.data, function (photo, done) {
request(photo.source).pipe(fs.createWriteStream(dir + "/" +photo.name));
console.log("copy of image " + img_basename);
}, function (err) {
if (err) {
console.log('An images failed to copy');
} else {
console.log('All 20 image have been copied successfully');
}
if (resf.paging && resf.paging.cursors) {
console.log("suite de l'album à venir");
next = resf.paging.cursors.after;
setTimeout(function () { callback(); }, 5000);
}
else {
console.log("Fin de l'album");
stop = true;
setTimeout(function () { callback(); }, 5000);
}
});
});
},
function (err) {
if (err) {
console.log('An images failed to process');
albumcallback();
} else {
console.log('All images in this group have been processed successfully');
albumcallback();
}
}
);// end while
我可能在复制了100个文件后崩溃了。我确定async.whilst和async.eachSeries是weel,因为我的日志显示每个调用都是串行的。但我崩溃了。我通过在每个副本之后等待等待来暂时解决问题:
request(photo.source).pipe(fs.createWriteStream(dir + "/" + img_basename));
console.log("copy of image " + img_basename);
setTimeout(function () { done(); }, 5000);
是请求模块的限制吗?如何更改此功能以确保在继续执行程序之前关闭每个连接?
答案 0 :(得分:2)
您可能需要转到异步循环。 <{3}}模块中eachLimit之类的东西可能是理想的。
async.eachLimit(photos, 10, function(photo, done) {
var r = request(photos[i].source).pipe(fs.createWriteStream(photos[i].name));
r.on('finish', done);
}, function(err) {
// All images done or there was an error
});
现在它将处理照片列表中的所有项目,但它只会同时处理其中的10个项目。这将阻止它启动数百或数千个并发传出连接。
答案 1 :(得分:0)
请求调用和管道调用是asyncrhon。所以我必须重写这一行:request(photos [i] .source).pipe(fs.createWriteStream(photos [i] .name));
见这里: Downloading N number of remote files using Node.js synchronously