async.retry-已调用回调
async.retry - Callback already called
我环顾四周,很确定回调没有被调用两次。不管怎样,下面是我的代码:
async.eachSeries(saveProps,function(photo,doneMaster){
var tries = 0;
async.retry({times: 10, interval: 200},
function(done, results){
debug('attempt num: ' + (++tries));
aws.getFile(photo.s3_location,function(err,s){
if(err){
debug('error:' + err);
return done(err);
}else{
done(null,s);
}
})
},
function(err,imageStream){
if(err){return doneMaster(err);}
else{
debug('appending photo to zip: %s', photo.s3_location);
zip.append(imageStream, {name: photo.saveName});
doneMaster();
}
}
);
},function(err){
if(err){
reject(err);
}else{
zip.finalize();
}
});
这个问题的一个小背景是,我试图以一种逐个的方式迭代一些照片信息,并将数据从s3流式传输到zip文件中。我正试图为许多照片(几千张)制作这个作品。由于一个图像返回ECONNRESET,因此进程会中断。每当发生这种情况时,我都想再试一次。我遇到的问题是,每当映像抛出ECONNRESET并重试时,异步库就会抛出一个回调已经调用的错误。我已经看了很久了,我不会叫它两次。
我的问题是,done()
怎么会被调用两次?
关于我正在使用的对象/包的一些信息:
- aws是knox
- zip是archiver
堆栈跟踪信息:
app:worker attempt num: 1 +1ms
app:worker error:Error: read ECONNRESET +91ms
/appdir/node_modules/async/dist/async.js:803
if (fn === null) throw new Error("Callback was already called.");
^
Error: Callback was already called.
at /appdir/node_modules/async/dist/async.js:803:36
at /appdir/node_modules/async/dist/async.js:3481:17
at /appdir/node_modules/async/dist/async.js:307:31
at /appdir/node_modules/async/dist/async.js:3755:21
at ClientRequest.<anonymous> (/appdir/modules/zip-worker.js:348:44)
at emitOne (events.js:77:13)
at ClientRequest.emit (events.js:169:7)
at TLSSocket.socketErrorListener (_http_client.js:256:9)
at emitOne (events.js:77:13)
at TLSSocket.emit (events.js:169:7)
at emitErrorNT (net.js:1253:8)
at nextTickCallbackWith2Args (node.js:442:9)
at process._tickCallback (node.js:356:17)
在这个堆栈跟踪中,/appdir/modules/zip-worker.js:348:44
是done(null,s);
所在的行。
因此,我发现一旦进程达到一定数量的流,该节点就很难处理所有流。因此,每个流都会被标记为完成,但在流被附加后的某个地方,其中一个连接会重置,导致回调重新启动并返回错误。因此,我决定不使用getFile
,而是使用get
,并单独处理每个图像数据。我可以附加图像缓冲区数据,而不是将流附加到zip。现在效果很好。以下是我的代码:
async.eachSeries(saveProps,function(photo,doneMaster){
var tries = 0;
async.retry({times: 10, interval: 200},
function(done, results){
var error;
var imageData;
debug('attempt num: ' + (++tries));
var req = aws.get(photo.s3_location);
req.on('response',function(res){
if(res.statusCode !== 200){
error = new Error('status code ' + res.statusCode);
}else{
res.on('data', function(chunk){
imageData += chunk;
});
res.on('end',function(){
if(error){
done(error);
}else{
done(null, imageData);
}
});
}
});
req.on('error', function(err){
error = err;
});
req.end();
},
function(err,data){
if(err){return doneMaster(err);}
else{
debug('appending photo to zip: %s', photo.s3_location);
zip.append(data, {name: photo.saveName});
doneMaster();
}
}
);
},function(err){
if(err){
debug('zip finished with error: ' + err);
reject(err);
}else{
debug('zip finalizing');
zip.finalize();
}
});
相关文章:
- 成功回调永远不会被JSONP请求调用
- 为什么(如何)'这'从函数内部调用回调时发生更改
- 如何在点击超链接时调用fullcalendar回调
- 在初始函数完成之前调用回调函数
- 未为路由器应用程序调用Node.Js的回调
- 对中的函数调用进行排序是回调的唯一方法
- Node.js exec调用从不调用回调
- 如何从参数数组中调用回调
- 当我的单元测试失败时,回调被调用了两次
- 回调函数(如afterMove)不被调用
- 如何使用jQuery等待来自回调的异步调用
- FireFox webrtc createoffer,没有任何回调调用
- 如何识别函数是作为方法调用还是作为回调调用
- jquery方法不是从angular回调调用的
- 从回调调用asyncwait
- 你可以使用PhoneGap和iOS从本地代码(而不是回调)调用javascript函数吗?
- Backbone model.fetch()回调(调用setTimeout)中的作用域问题
- React.js:你用一个不可调用的回调调用了' setState '
- 从图表.js选项回调调用 TypeScript 函数
- 如何将js函数从异步调用转换为回调调用