2015-08-21 7 views
0

Вот мой код:ожидания на обратный вызов nodejs

for (var i = 0; i < items.length; i++) { 
    doSomeWork('Company","{message : "message"}'); 
} 

doSomeWork = function (companyIdentifier,item) { 
    var serialisedMessage = new serialisedMessageWithMetadata(item); 

    //I want this to block until the callback inside send is fired. 
    send(companyIdentifier, serialisedMessage.getJSON()); 
} 

send = function (queueId, msg) { 
    var sqsQueueUrl = this.createQueueUrl(queueId); 

    var sqsParams = { 
     MessageBody: JSON.stringify(msg), 
     QueueUrl: sqsQueueUrl 
    }; 

    sqs.sendMessage(sqsParams, function (err, data) { 
     if (err) { 
      console.log('ERR', err); 
     } 
     else { 
      console.log(data); 
     } 
    }); 
} 

Я хочу, чтобы мой цикл для ожидания на обратный вызов в SendMessage увольняют. Просматривая некоторые статьи в Google, я начал думать, что обещания - это то, что мне было нужно, но это кажется очень сложным способом просто заблокировать функцию (и я не смог заставить эти примеры работать!)

Я подозреваю, что это что-то базовый я пропустил, и надеялся на что-то вроде «жду».

Любая помощь будет оценена по достоинству.

ответ

1

Вы не можете заблокировать Javascript, ожидающий завершения операции async. Это просто не работает. Если вы хотите сериализовать свои сообщения, чтобы отправить их, будет получен успешный ответ, затем будет отправлен следующий, тогда вам придется специально писать код для последовательной асинхронной операции. Существует ряд подходов.

Вот некоторые примеры решения этой проблемы:

Making async javascript task in a loop

How to synchronize a sequence of promises?

Questions from the synchronous node.js

Вот одна идея, как перестроить свой код, чтобы заставить его работать последовательно:

function doAllWork(items, companyIdentifier) { 
    var cntr = 0; 

    function send(queueId, msg, done) { 
     var sqsQueueUrl = this.createQueueUrl(queueId); 

     var sqsParams = { 
      MessageBody: JSON.stringify(msg), 
      QueueUrl: sqsQueueUrl 
     }; 

     sqs.sendMessage(sqsParams, function (err, data) { 
      if (err) { 
       console.log('ERR', err); 
      } 
      else { 
       console.log(data); 
      } 
      done(err, data); 
     }); 
    } 

    function doSomeWork() { 
     // if still more do do, then do the next one 
     if (cntr < items.length) { 
      var serialisedMessage = new serialisedMessageWithMetadata(items[cntr++]); 

      //I want this to block until the callback inside send is fired. 
      send(companyIdentifier, serialisedMessage.getJSON(), function(err, data) { 
       if (!err) { 
        // do next iteration 
        doSomeWork(); 
       } 
      }); 
     } 
    } 
} 

doAllWork(items, 'Company","{message : "message"}'); 
0

Добавив обратный вызов к вашей функции отправки и используя модуль npm async для блокировки цикла for. Что-то вроде этого?

async.forEach(items,function(item,innerCallback){ 
     var serialisedMessage = new serialisedMessageWithMetadata(item); 

     //I want this to block until the callback inside send is fired. 
     send(companyIdentifier,  serialisedMessage.getJSON(),function(err,res){ 
      if(!err){ 
       console.log("SUCCESS"); 
      }else{ 
       console.log("SUCCESS"); 
      } 
      innerCallback(); 
     }); 
    },function(err,res){ 
     console.log("Finsied sending msgs"); 
    }) 

    send = function (queueId, msg,callback) { 
     var sqsQueueUrl = this.createQueueUrl(queueId); 

     var sqsParams = { 
      MessageBody: JSON.stringify(msg), 
      QueueUrl: sqsQueueUrl 
     }; 

     sqs.sendMessage(sqsParams, function (err, data) { 
      if (err) { 
       console.log('ERR', err); 
       callback(true,"ERROR") 
      } 
      else { 
       console.log(data); 
       callback(null,data) 
      } 
     }); 
    }