2017-01-13 7 views
1

私は滝の非同期をしようとしていますが、私は期待した出力を得られません。 クエリの代わりに配列を使用すると、基本的に私の滝が正常に動作します。 だから、私はクエリのコールバックに何か間違っていると思います。asyncの滝が次の順序でない場合mysqlのクエリ

コード、それは私は、配列を使用して期待するもので動作します:

function range(start, end) { 
    var foo = []; 
    for (var i = start; i <= end; i++) { 
     foo.push(i); 
    } 
    return foo; 
} 
users = range(1,2) 
obj = [1,2]; 
async.forEachLimit(users, 1, function(user, userCallback){ 
    async.waterfall(
     [ 
      function(callback) { // query the data to get the category and specific number of rows 
      results = {sku_config:'A',img:'http//blabla',sku_config:'B',img:'http//bloblo'} 
      callback(null, results); 


      }, 
      function(obj,callback) { 
       async.eachSeries(obj, function (sku, callback) { 
        var url = sku.img; 
        var sku = sku.sku_config; 
        console.log("loop"); 
          request.get(url, {encoding: null} , function(error, response, body) { 
           console.log('request'); 
          }); 

        callback(null); 
       }, function(responsetoendofloop){ 
         callback(null); 
       }); 
      }, 
     ], 
     function (err) { 
      console.log('Finish'); 
      userCallback(null); 
     } 
    ); 
}, function(err){ 
    console.log("User For Loop Completed"); 
}); 

出力:

loop 
request 
loop 
request 
Finish 
loop 
request 
loop 
request 
Finish 
User For Loop Completed 

しかし、私は、MySQLとのデータを照会しようとここで問題 コードが来ます

async.forEachLimit(users, 1, function(user, userCallback){ 
    async.waterfall(
     [ 
      function(callback) { // query the data to get the category and specific number of rows 
       connection.query(query_sku, 
       ['Fashion',1,2], 
        function(err, results, fields) { 
         if (err) 
          throw err; 
       callback(null, results); 
       }); 

      }, 
      function(obj,callback) { 
       async.eachSeries(obj, function (sku, callback) { 
        var url = sku.img; 
        var sku = sku.sku_config; 
        console.log("loop"); 
          request.get(url, {encoding: null} , function(error, response, body) { 
           console.log('request'); 
          }); 

        callback(null); 
       }, function(responsetoendofloop){ 
         callback(null); 
       }); 
      }, 
     ], 
     function (err) { 
      console.log('Finish'); 
      userCallback(null); 
     } 
    ); 
}, function(err){ 
    console.log("User For Loop Completed"); 
}); 

出力:

loop 
loop 
Finish 
loop 
loop 
Finish 
User For Loop Completed 
request 
request 
request 
request 

すべての要求は、最後に実行されます:(

あなたは私が修正できるものにアイデアを持っている場合。 ありがとう

答えて

1

最初の問題は、コールバックの名前がまったく同じで、重大な問題が発生する可能性があることです。呼び出す意味のコールバックは区別できません。これにより、後で実行する必要のないコードをプログラムで実行する可能性があります。

第2の問題は、コールバックがrequest.get関数の外部に置かれていることです。ノードjsの性質は、request.get関数が戻るまで待たずに、代わりにコールバックをただちに呼び出すことを意味します。 request.get関数の中にコールバックを置くことによって、リクエスト関数が返ってからコールバックが呼び出されるまで強制的に待機します。コードの改訂版は以下の通りです。

async.forEachLimit(users, 1, function(user, userCallback){ 
    async.waterfall(
    [ 
     function(callback) { // query the data to get the category and specific number of rows 
      connection.query(query_sku, 
      ['Fashion',1,2], 
       function(err, results, fields) { 
        if (err) 
         throw err; 
        callback(null, results); 
      }); 

     }, 
     function(obj,callback) { 
      async.eachSeries(obj, function (sku, seriesCallback) { 
       var url = sku.img; 
       var sku = sku.sku_config; 
       console.log("loop"); 
       request.get(url, {encoding: null} , function(error, response, body) { 
        console.log('request'); 
        seriesCallback(null); 
       }); 

      }, function(responsetoendofloop){ 
        callback(null); 
      }); 
     }, 
    ], 
    function (err) { 
     console.log('Finish'); 
     userCallback(null); 
    }); 
}, function(err){ 
    console.log("User For Loop Completed"); 
}); 
+0

非常に明確です!あなたの最初のポイントについては、コールバックの名前は各関数のスコープを尊重する同じ名前を持っていますが、私はそのイベントを前提としていました。しかし、私は彼らの名前を変更する良い習慣を取る – patrick

+0

あなたは大歓迎です!私はあなたに助けになることができてうれしい!これはコールバックのスコープが尊重されているのは事実かもしれませんが、異なる名前を付けることは間違いなく良い方法です。これにより、複数のネストされた非同期メソッドが使用されているときに混乱が避けられ、必要に応じて実際に親メソッドのコールバックを指定できるようになります。 –

1

callback(null);async.eachSeriesはリクエスト後です。

このようにリクエストを入れるだけで修正できます。

request.get(url, {encoding: null} , function(error, response, body) { 
    console.log('request'); 
    callback(null); 
}); 

また、実際に名前を変更するコールバック関数を明確にする必要があります。例えば、コールバックのeachSeriesコール内next

function(obj,callback) { 
    async.eachSeries(obj, function (sku, next) { 
     var url = sku.img; 
     var sku = sku.sku_config; 
     console.log("loop"); 
     request.get(url, {encoding: null} , function(error, response, body) { 
      console.log('request'); 
      next(null); 
     }); 
    }, function(responsetoendofloop){ 
      callback(null); 
    }); 
} 

は、この情報がお役に立てば幸いです。

関連する問題