1

我是 Nodejs 新手,需要一些指导来编写更好的代码。这是我的问题。

我有一个功能,我正在使用异步瀑布模型。我想在循环中调用该函数并在中间出现问题时中断循环,否则在 for 循环结束时通知一些结果。但由于某种原因,我得到了一个未定义的响应。

function myFunc (arg1) {
     async.waterfall(
           [
               function() {
                        //do something
                        callback(null, data);
               },
               function(data, callback) {
                       //do something
                       callback(null, 'done');
               }
           ],
           function(err, result) {
               return {"error" : err, "res" : result};
           }
}

//Here I am calling my function 
for (var d in mydata) {
    var retdata =  myFunc (mydata[d]); //retdata has undefined in it as this line executes before the last function of water fall
    if (retdata.error !== 200) {
          return //  break loop
     }
  }
//Other wise if every thing is fine nofify after the for loop end
console.log ("done");

简而言之,当瀑布的最后一个函数给出错误时,在结束时通知结果(如果为真)或中断循环的正确和最佳方式是什么。

4

2 回答 2

2

您不能使用同步方法(如 for 循环)并期望您的代码等到异步任务完成。您不能使用 return 从异步函数中获取数据。

这是一种使用async.map. 注意回调结构。还要确保您指的是异步文档

//Async's methods take arrays:

var mydata = {a: 'foo', b: 'bar'};
var myarr;
for (var d in mydata) {
  myarr.push(mydata[d]);    
  // Beware, you might get unwanted Object properties
  // see e.g. http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript/3010848#3010848
}

async.map(myarr, iterator, mapCallback);

function iterator(d, done){
  // async.map will call this once per myarr element, until completion or error
  myFunc(d, function(err, data){
    done(err, data);    
  });
};

function mapCallback(err, mapped){
  // async.map will call this after completion or error
  if(err){
    // Async ALREADY broke the loop for you.
    // Execution doesn't continue if the iterator function callsback with an
    // error.
  };
  console.log("Asynchronous result of passing mydata to myfunc:");
  console.log(mapped);
  // mapped is an array of returned data, in order, matching myarr.
};


function myFunc (arg1, callback) {
  async.waterfall(
  [
    function(done) {
      //do something
      done(null, data);
    },
    function(data, done) {
      //do something
      done(null, 'done');
    }
  ],
  function(err, result) {
    if (result !== 200) {
      return callback('Non-200');  
      // This return is important to end execution so you don't call the callback twice
    }

    callback(err, result);
  }
}
于 2014-08-05T22:04:29.340 回答
1

您正在尝试混合同步和异步控制流。问题是您对 myFunc 的调用将在 myFunc 中的任何瀑布函数执行之前立即返回。

这是一个可行的真实示例。它遍历数组并在看到 5 时以错误终止:

var async = require('async');

function myFunc(data, cb) {
   async.waterfall(
       [
           function(callback) {
             //do something
             callback(null, data);
           },
           function(data, callback) {
             //do something
             if (data === 5) {
                callback("Five", null);   // Throw error if we see 5
             } else {
                callback(null, 'done');
             }
           }
       ],
       function(err, result) {
           cb(err, result);
       }
   );
}

var mydata = [1,2,3,4,5,6];
async.eachSeries(mydata, function(d, cb) {
   console.log('Processing ' + d);
   myFunc(d, cb);
}, function(err) {
   // error happened in processing d
   // handle error
   console.log('Error ' + err);
});
于 2014-08-05T22:05:52.703 回答