数组和异步函数回调

时间:2013-07-25 13:57:06

标签: javascript

我有异步功能:

var func = function  (arg, next) {
    var milliseconds = 1000;
    setTimeout(function(){
        console.log (arg);
        next()
    }   , milliseconds);
}

并且数组:

var arr = new Array();
arr.push (0);
arr.push (1);

console.log(arr);

我想对我的数组func的每个项目使用arr

func(arr[0], function(){
    func(arr[1], function(){
        console.log("finish");
    })
})

好的数组由2个元素组成,但如果我有1000个元素的数组,如何对func中的每个项使用arr

如何在周期中完成?

7 个答案:

答案 0 :(得分:3)

var arrayFunc = function(array) {
  if (array.length > 0) {
    func(array[0], function() { arrayFunc(array.slice(1)); });
  }
}

这将使用数组中的第一个元素运行函数,然后使用continuation函数获取数组的其余部分。因此,当它运行时,它将在数组中运行新的第一个元素。

编辑:这是一个不会复制阵列的修改版本:

var arrayFunc = function(array, index) {
  if (index < array.length) {
    func(array[index], function() {
      var newI = index + 1;
      arrayFunc(array, newI);
    });
  }
}

只需在索引为0时第一次调用它。

答案 1 :(得分:0)

虽然您的方法有效,但如果您的呼叫数量不确定,则无法使用它,因为您的异步命令中的每个链都是硬编码的。

如果要在数组上应用相同的功能,最好提供一个创建内部函数的函数,并在其内部函数上应用超时:

var asyncArraySequence = function (array, callback, done){
  var timeout = 1000, sequencer, index = 0;

  // done is optional, but can be used if you want to have something
  // that should be called after everything has been done
  if(done === null || typeof done === "undefined")
    done = function(){}

  // set up the sequencer - it's similar to your `func`
  sequencer = function(){
    if(index === array.length) {
      return done();      
    } else {
      callback(array[index]);
      index = index + 1;
      setTimeout(sequencer, timeout);
    }
  };
  setTimeout(sequencer, timeout);
}

var arr = [1,2,3];
asyncArraySequence(arr, function(val){console.log(val);});

答案 2 :(得分:0)

一个简单的异步循环:

function each(arr, iter, callback) {
    var i = 0;
    function step() {
        if (i < arr.length)
            iter(arr[i++], step);
        else if (typeof callback == "function")
            callback();
    }
    step();
}

现在使用

each(arr, func);

答案 3 :(得分:0)

您可以尝试arr.map

var func = function  (arg, i) {
    var milliseconds = 1000;
    setTimeout(function(){
        console.log (arg);
    }, milliseconds*i);
}

var arr = new Array();
arr.push (0);
arr.push (1);

arr.map(func);

DemoPolyfill for older browsers

更新:我认为OP想要遍历数组并使用每个数组项调用回调函数但我可能错了,所以不是删除答案我是把它放在这里,也许将来对其他人有帮助。这不能回答当前的问题。

答案 4 :(得分:0)

一个简单的解决方案是:

var fn = arr.reduceRight(function (a, b) {
  return func.bind(null, b, a);
}, function() {
  console.log('finish');
});

fn();

演示:http://jsbin.com/isuwac/2/


或者如果可以更改func参数的顺序以接收next回调作为第一个参数,则可以这样简单:

['a', 'b', 'c'].reduceRight(func.bind.bind(func, null), function (){
  console.log('finish');
})();

演示:http://jsbin.com/ucUZUBe/1/edit?js,console

答案 5 :(得分:0)

Thanx,@ Herms。工作解决方案:

var arrayFunc = function(array) {
  if (array.length > 0) {
    func(array[0], function() {arrayFunc(array.slice(1)); });
  }
  else
  {
    console.log("finish");
  }
}
arrayFunc(arr);

答案 6 :(得分:-1)

您可以遍历数组

for(var i = 0; i < arr.length; i++){
    func(arr[i], function(){...});
}