如何在下次通话前重复拨打电话并等待完成?

时间:2013-06-18 13:26:46

标签: javascript node.js

我正在使用node.js

我有一个函数,我需要在循环中调用几个参数。必须使用循环迭代器作为参数调用该函数,并且循环在完成处理之前不得再次调用该函数。

像这样的东西(同步方法): (注意someFunc是一个异步函数)

var totCount = 1000;
for (var x = 0 ; x < totCount ; x++) {
    someFunc(x, parm2, parm3, parm4);
}

我理解在节点中, someFunc 可以按任何顺序执行,但对于这种情况,它绝对必须用x = 0然后1然后2等执行。

似乎异步库调用“async.whilst”会执行此操作,但我无法将示例转换为我的真实代码。

以下是“async.whilst”

的示例
var count = 0;

async.whilst(
    function () { return count < 5; },
    function (callback) {
        count++;
        setTimeout(callback, 1000);
    },
    function (err) {
        // 5 seconds have passed
    }
);

请注意,由于我可能需要多次调用函数 someFunc ,因此正常的回调方法将无效。

如何将其转换为我的代码? (我假设“async.whilst”是正确的方法。如果没有,请指出正确的方法)

2 个答案:

答案 0 :(得分:1)

听起来你想使用promises,假设你可以设置someFunc以便它返回一个promise。你可以这样做:

var promise=new Promise().fulfill();
var totCount = 1000;
for (var x = 0 ; x < totCount ; x++) {
    promise=promise.then(function(){return someFunc(x, parm2, parm3, parm4);});
}
promise.then(function(){console.log("done");});

确切的语法取决于您选择使用的promises库。

答案 1 :(得分:1)

以下示例将起作用,假设someFunc是异步并将回调作为最后一个参数。它是否确实取决于它是如何实现的。如果它可能是另一个库的一部分。

var count = 0;
var totCount = 1000;

async.whilst(
  function () { return count < totCount; },
  function (callback) {
    someFunc(count, parm2, parm3, parm4, callback);
    count++;
  },
  function (err) {
      // someFunc has been called totCount times, or an error has occured
  }
);

如果someFunc不是异步但你想异步运行循环以避免阻塞,你只需在函数调用后调用回调。

//...
  function (callback) {
    someFunc(x, parm2, parm3, parm4);
    count++;
    callback();
  },
// ...

<强>更新

没有异步/承诺(未经测试):

var count = 0;
var totCount = 1000;

function loop () {
  // Async lets you provide you own check-method
  if(count >= totCount) {
    // Async lets you provide your own done-method
    return done();
  }

  // Async does setImmediate/process.nextTick somewhere around here
  myFunc(count, param, param, function() {
    // Async checks for errors here
    count++;
    loop();
  });
}

function done () {
  // Async provides any errors here
  console.log("done");
}

我评论了async做了一些额外的东西,这可能是最好的(大多数情况下,查看特定的源代码,它非常容易阅读)。例如,如果someFunc实际上不是异步但只是调用回调,那么就像使用for(...)一样杀死事件循环。