2015-12-22 2 views
1

Уверен, у меня есть общая проблема, но поскольку я еще новичок в async javascript, я не уверен, какое (лучшее) решение для моей проблемы.Переменные цикла async Javascript

Я прохожу через цикл for, и в этом цикле я вызываю метод, включающий метод обратного вызова. В методе обратного вызова я хочу знать, какой цикл является последним. Но для этого требуется немного времени, и в тот момент, когда он будет завершен один раз, цикл for вокруг него закончен, а переменная счетчика i уже находится на самом высоком уровне. Поэтому мой вопрос: как определить последний цикл в методе обратного вызова?

Вот пример кода для этого.

var i; 
for (i = 0; i < numMessages; i++){ 
    var lastMessage; 
    if (i+1 === numMessages) { 
     lastMessage = true; 
    } 
    else { 
     lastMessage = false; 
    } 
    twilioClient.sendMessage({ 
     to: recipientNumber, 
     from: zenyaTwilioNumber, 
     body: (numMessages > 1? (i+1) + '/' + Math.ceil(options.messageBody.length/153) + ': ' + options.messageBody.substring(i*153, (i+1)*153): options.messageBody) 
    }, 
    function (err, res) { 
     if (err) { 
      callback({error: err}); 
     } 
     else { 
      console.log('Message:' +i); 
      console.log('numMessages: ' + numMessages); // Even after method is executed once, the lastMessage variable is already true 
      if (lastMessage) { 
       var returnObj = { 
        status : status, 
        recipient : res.to, 
        statusMessage : res.status 
       }; 
       callback({result: returnObj}); // The callback should only be called once here. 
      } 
     } 
    }); 
} 

С нетерпением ждем ваших ответов и ознакомьтесь с лучшей практикой о том, как этого достичь.

Спасибо, Benni

+2

Закрытие вопрос: https://stackoverflow.com/questions/ 111102/how-do-javascript-closures-work? Rq = 1 Вы должны захватить переменную. О циклах: [Закрытие JavaScript внутри циклов - простой практический пример] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Shanoor

ответ

0

Вам нужно создать функцию, которая:

  • принимает параметры, которые вы хотите получить доступ в функцию обратного вызова
  • возвращает функцию обратного вызова

Тогда вы вызываете эту функцию с фактическими значениями параметров.

Таким образом, вместо:

function (err, res) { 
    // ... 
} 

Понадобится:

(function(i, lastMessage) { 
    return function(err, res) { 
     // ... 
    } 
})(i, lastMessage) 

Применяя его к примеру:

var i; 
for (i = 0; i < numMessages; i++){ 
    var lastMessage; 
    if (i+1 === numMessages) { 
     lastMessage = true; 
    } 
    else { 
     lastMessage = false; 
    } 
    twilioClient.sendMessage({ 
     to: recipientNumber, 
     from: zenyaTwilioNumber, 
     body: (numMessages > 1? (i+1) + '/' + Math.ceil(options.messageBody.length/153) + ': ' + options.messageBody.substring(i*153, (i+1)*153): options.messageBody) 
    }, 
    (function(i, lastMessage) { 
     return function (err, res) { 
      if (err) { 
       callback({error: err}); 
      } 
      else { 
       console.log('Message:' + i); 
       console.log('numMessages: ' + numMessages); 
       if (lastMessage) { 
        var returnObj = { 
         status : status, 
         recipient : res.to, 
         statusMessage : res.status 
        }; 
        callback({result: returnObj}); // The callback should only be called once here. 
       } 
      } 
     }; 
    })(i, lastMessage)); 
} 
+0

Удивительно, что отлично работало. Большое спасибо! – bdifferent

+0

@bdifferent Классно! –

Смежные вопросы