2017-01-13 20 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); 
    }); 
} 

希望这有助于例如回调。