2017-01-13 152 views
1

我想做一個瀑布異步,但我沒有得到我想要的預期輸出。 基本上我的瀑布按預期工作,如果我使用數組而不是查詢 所以我想我在查詢的回調上做了錯誤,但我不知道是什麼。當它與我的期望使用數組當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

您遇到的第一個問題是您的回調具有完全相同的名稱,這可能會導致嚴重問題。您有意調用的回調無法區分,這可能會導致您的程序執行不應在稍後執行的代碼段。

第二個問題是回調放在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); 
    }); 
} 

希望這有助於例如回調。