如何使循环同步?

时间:2010-12-27 16:16:35

标签: javascript javascript-events node.js

如何使这个循环同步?提前谢谢。

代码

// (...)

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 个答案:

答案 0 :(得分:5)

更新回答

更新你的更新问题,对sendMessage的调用是同步的,所以你必须调用一个异步的函数(如下所述)。 NodeJS文档中未列出sendMessage。您必须从它获得的任何来源中找到它的同步版本,或使用其回调机制:

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);
}

答案 1 :(得分:0)

我不熟悉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
  }
}

上述方法的缺点是,如果sendMessage()或回调中出现错误,您可能会发现自己处于while()语句的无限循环中。

另一种方法是允许你异步发送所有消息,然后在继续之前等待它们全部完成,然后执行以下操作:

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,这将产生无限循环的相同问题。