2016-05-02 16 views
0

かなり見てきましたが、私はコールバックが2回呼び出されていないことを確信しています。 、この問題のasync.retry - コールバックは既に呼び出されています

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(); 
    } 
}); 

少し背景私は1対1の方式で、いくつかの写真情報を反復処理、およびへのS3からデータをストリーミングしようとしているということです:とにかく、ここでは以下の私のコードですzipファイル私は多くの写真(数千)のためにこの作品を作ろうとしています。 1つのイメージがECONNRESETを返すため、プロセスがトリップします。これが起こるたびに、もう一度やり直したい。私が抱えている問題は、イメージがECONNRESETをスローして再試行するたびに、非同期ライブラリがコールバックが既に呼び出されているというエラーが発生することです。私はこれを永遠に見てきました。私はそれを二度と呼んでいません。

私の質問、どうすればdone()を2回呼び出すことができますか?

オブジェクト/私が使用しているパッケージに関するいくつかの情報:

スタックトレース情報:このスタックで

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は012の行ですです。

+0

2つのエラーが発生したらどうなりますか? – SLaks

+0

あなたは精緻化できますか? –

+0

申し訳ございません。私はあなたのコードを誤解しました。コールバックエラーのスタックトレースとは何ですか? – SLaks

答えて

0

これで、プロセスが一定量のストリームを取得すると、そのノードがすべてのストリームを処理するのに苦労していることが分かりました。したがって、各ストリームは完了としてマークされますが、ストリームが追加された後のいずれかで、接続の1つがリセットされ、そのコールバックがエラーで再構築されます。だから、私はgetFileの代わりにgetを使い、それぞれの画像データを個別に扱うことにしました。ストリームをジップに追加する代わりに、イメージバッファデータを追加することができます。今は美しく動作します。以下は私のコードです:

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(); 
    } 
}); 
関連する問題