Как сделать для цикла синхронным? - PullRequest
0 голосов
/ 27 декабря 2010

Как сделать это для цикла синхронным?Заранее спасибо.

Код

// (...)

object = {
  'item1': 'apple',
  'item2': 'orange'
};

// (...)

for(var key in object) {

  // do something async...
  request.on('response', function (response) {
    response.on('data', function (chunk) {

      console.log('The message was sent.');

    });
  });

}

console.log('The for cycle ended.');

Выход

The for cycle ended.
The message was sent.

Хотелось бы увидеть этот тип вывода ...

The message was sent.
The for cycle ended.

Ответы [ 2 ]

5 голосов
/ 27 декабря 2010

Обновленный ответ :

В вашем обновленном вопросе вызов sendMessage является синхронным, поэтому вы должны вызывать функцию, которая выполняет что-то асинхронное (как я упоминал ниже).sendMessage не указан в документации NodeJS.Вам нужно будет найти его синхронную версию из любого источника, из которого вы ее получили, или использовать механизм обратного вызова:

var obj, keys, key, index;

// Define the object
obj = {
  'item1': 'apple',
  'item2': 'orange'
};

// Find its keys (you can just type in the array if they don't
// need to be discovered dynamically)
keys = [];
for (key in obj) {
    keys.push(key);
}

// Start the loop
index = 0;
process();

// This function gets called on each loop
function process() {
    // Are we done?
    if (index >= keys.length) {
        // Yes
        console.log("The cycle ended");
    }
    else {
        // No, send the next message and then
        // use this function as the callback so
        // we send the next (or flag that we're done)
        sendMessage(obj[keys[index++]], process);
    }
}

Оригинальный ответ :цикл является синхронным.Вы должны сделать что-то вроде setTimeout или что-то подобное, чтобы сделать его * a * синхронным.

Вызовы, которые вы делаете для NodeJS, могут быть не синхронными.Вы должны вызывать xyzSync версии вещей, если вы хотите синхронные вызовы.

Продолжая гадать, что вы могли бы иметь в виду, если вы хотите сделать цикл * a * синхронным:

var obj, key;

// Define the object
obj = {
  'item1': 'apple',
  'item2': 'orange'
};

for (key in obj) {
  schedule(key);
}

function schedule(k) {
    setTimeout(function() {
        // Do something with obj[k]
    }, 0);
}
0 голосов
/ 27 декабря 2010

Я не знаком с node.js, но я бы предположил, что:

function() {
  console.log('The message was sent.');
}

- это функция обратного вызова, которая вызывается после успешной отправки сообщения. И что фактическая отправка сообщения является асинхронной, чтобы не блокировать остальную часть выполнения. Если вы хотите сделать это блокирующим / синхронным процессом, вы можете сделать что-то вроде этого: (обратите внимание, может быть явный способ сделать синхронный вызов в node.js, я просто не знаком с этим):

for(var key in object) {
  var completed = false;
  sendMessage('Hello!', function() {
    console.log('The message was sent.');
    completed = true;
  });

  while(completed == false) {
    ; // do nothing
  }
}

Недостатком вышеупомянутого подхода является то, что вы можете оказаться в бесконечном цикле в операторе while (), если когда-либо возникнет ошибка в sendMessage () или обратном вызове.

Другой подход, который позволил бы вам отправлять все сообщения асинхронно, но затем ждать их завершения, прежде чем двигаться дальше, заключается в том, чтобы сделать что-то вроде:

var count = 0;
for(var key in object) {
  count++;
  sendMessage('Hello!', function() {
    console.log('The message was sent.');
    count--;
  });
}

while(count > 0){ 
  ; // wait until all have finished
}

Это будет иметь ту же проблему бесконечного цикла, если когда-либо возникнет ошибка, которая не позволит счетчику снова достичь 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...