如果我使用循环如何解决回调函数?

时间:2015-11-12 23:03:58

标签: javascript node.js

我在解决下面的脚本时遇到问题,如果你注意到我已插入控制台日志(1111111)(2222222)(333333)来跟踪代码,当我运行脚本时,控制台会按如下方式写入日志: 1111111 3333333 2222222 2222222这是因为回调

我想在跳过剩余代码之前运行for循环,并且控制台的顺序为1111111 2222222 2222222 3333333

你能帮我解决这个问题吗?

    function sendNotification(executionID){
    db.collection('emailsettings', function(err, collection) {
        db.collection('executions', function(err, EXEcollection) {
            db.collection('executiontestcases',function(err,tcs){
                db.collection('testcases',function(err, testcasename){
                    collection.findOne({}, {}, function(err, settings) {
                        EXEcollection.findOne({_id:executionID}, {}, function(err, execution) {
                            tcs.find ({executionID:executionID}).toArray(function(err,items){
                    if(!execution.emails) return;
                    if(execution.emails.length == 0) return;
                    if((!settings.host) || (settings.host == "")) return;
                    var options = {};

                    var subject = "SOUQ Automation: " + execution.name;
                    if(parseInt(execution.failed) > 0){
                        subject = subject + " (CONTAINS FAILURES)"
                    }
                    else{
                        subject = subject + " (ALL PASSED)"
                    }
                    var body = "Start Of HTML CODE";
                    console.log("111111111");
                    for (var i=0; i<items.length;i++){
                        (function(i){
                        testcasename.findOne({ _id:require('mongodb').ObjectID(items[i].testcaseID)},function(err,tcsname){
                        body += "<tr>";
                        body += "<td>";
                        body += tcsname.name;
                        body += "<\td>";
                        body += "<td>";
                        body +=items[i].result;
                        body += "<\td>";
                        body += "<\tr>";
                        console.log("2222222222");
                        });
                        })(i);
                    }
                    console.log("3333333333");
                    body += "END OF HTML";
                    if(settings.user){
                        options.auth = {user:settings.user,pass:settings.password}
                    }
                    options.host = settings.host;
                    if((settings.port)&&(settings.port!="")){
                        options.port = parseInt(settings.port);
                    }
                    else{
                        options.port = 25
                    }
                    var smtpTransport = nodemailer.createTransport("SMTP",options);
                    var toList = "";
                    execution.emails.forEach(function(email){
                        if(toList == ""){
                            toList = email
                        }
                        else{
                            toList = toList + "," + email
                        }
                    });
                    var mailOptions = {
                        from: "m@m.com",
                        to: toList,
                        subject: subject,

                        html: body 
                    };
                    });
                });
            });
            });
    })
    })
    });
}

1 个答案:

答案 0 :(得分:0)

将此功能添加到您的代码中。

//A function to wait until either times up, or until a pass in "funct" returns "true", which ever occured first.
//funct - callback function, to be returned true or false.
//done - an optional callback function for notify when waiting is over.
//timeout - the amount of time in million-second to wait.
//caller - string, optional to identify the caller for monitoring purpose.
function waitToSync(funct, done, timeout, caller) {
  //This is  a hack synchronize to wait until funct() returns true or timeout becomes < 0.
  caller = caller || '';
  if ((funct === undefined) || typeof (funct) != 'function') return;
  function waiting() {
    if (!funct()) {
      var dt = new Date();
      //console.log("Waiting: " + dt.format('yyyy-mm-dd h:MM:ss'));
      if ((timeout - 1000) > 0)
        setTimeout(waiting, 1000); //1 second.
      else {

        console.log(caller + ': waitToSync timed out!!!');
        document.body.style.cursor = 'default';
      }
      timeout -= 1000;
    }
    else {
      if (done !== undefined && (typeof done === 'function'))
        done();
    }
  }
  waiting();
}

更改内容如下:

  var areWeDone = false; //synching flag.
  var body = "Start Of HTML CODE";
  console.log("111111111");
  for (var i = 0; i < items.length; i++) {
    (function (i) {
      testcasename.findOne({ _id: require('mongodb').ObjectID(items[i].testcaseID) },
    function (err, tcsname) {
      body += "<tr>";
      body += "<td>";
      body += tcsname.name;
      body += "<\td>";
      body += "<td>";
      body += items[i].result;
      body += "<\td>";
      body += "<\tr>";
      console.log("2222222222");
      areWeDone = i >= items.length; //doing a test for True when you're done.
      });
    })(i);
  }
  waitToSync(function () { return areWeDone; },
 function () {
   //TODO: do all you subsequence code inside this callback function.
   console.log("3333333333");
   body += "END OF HTML";
 }, 10000, "testing");

等待最多10秒或直到“areWeDone”为真。 你明白了。