4

我有异步功能:

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

如何在循环中做到这一点?

4

7 回答 7

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

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

编辑:这是一个不复制数组的修改版本:

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

第一次调用它,索引为 0。

于 2013-07-25T14:01:57.277 回答
0

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

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

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);});
于 2013-07-25T14:08:07.083 回答
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);
于 2013-07-25T14:10:08.530 回答
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

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

于 2013-07-25T14:13:34.410 回答
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可以更改 's 参数的顺序以接收next回调作为第一个参数,则可以很简单:

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

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

于 2013-07-25T14:18:45.400 回答
0

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

var arrayFunc = function(array) {
  if (array.length > 0) {
    func(array[0], function() {arrayFunc(array.slice(1)); });
  }
  else
  {
    console.log("finish");
  }
}
arrayFunc(arr);
于 2013-07-25T14:52:11.327 回答
-1

您可以遍历数组

for(var i = 0; i < arr.length; i++){
    func(arr[i], function(){...});
}
于 2013-07-25T13:59:34.427 回答