简体   繁体   English

数组和异步函数回调

[英]array and asynchronous function callback

I got async function: 我有一个异步功能:

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

And array: 和数组:

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

console.log(arr);

I want to use func for every item of my array arr : 我想对数组arr每个项目使用func

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

Ok for array consisted of 2 elements, but if I got array of 1000 elements how to use func for every item in arr ? 确定数组由2个元素组成,但是如果我得到1000个元素的数组,如何对arr每个项目使用func

How to do it in cycle? 如何循环执行?

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

This will run your function with the first element in the array, and then have the continuation function take the rest of the array. 这将使用数组中的第一个元素运行您的函数,然后让延续函数使用数组的其余部分。 So when it runs it will run the new first element in the array. 因此,当它运行时,它将运行数组中的新第一个元素。

EDIT: here's a modified version that doesn't copy the array around: 编辑:这是一个修改后的版本,不会在周围复制该数组:

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

And just call it the first time with an index of 0. 并以索引0首次调用它。

While your approach is valid, it's not possible to use it if you have an uncertain number of calls, since every chain in your async command is hardcoded. 尽管您的方法有效,但如果调用次数不确定,则无法使用该方法,因为异步命令中的每个链都是硬编码的。

If you want to apply the same functionality on an array, it's best to provide a function that creates an internal function and applies the timeout on it's inner function: 如果要在数组上应用相同的功能,则最好提供一个函数,该函数创建一个内部函数并将超时应用于其内部函数:

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

A simple asynchronous loop: 一个简单的异步循环:

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

Now use 现在使用

each(arr, func);

You may try arr.map 您可以尝试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);

Demo and Polyfill for older browsers . 适用于旧版浏览器的 演示Polyfill

Update : I thought the OP wants to loop through the array and call the callback function with each array item but I was probably wrong, so instead of deleting the answer I'm just keeping it here, maybe it would be helpful for someone else in future. 更新:我以为OP希望循环遍历数组并为每个数组项调用回调函数,但我可能是错的,因此与其删除答案,我只是将其保留在此处,也许对其他人有所帮助未来。 This doesn't answer the current question. 这不能回答当前的问题。

A simple solution would be: 一个简单的解决方案是:

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

fn();

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


or if the order of func 's parameters could be changed to receive the next callback as the first parameter, it could be as simple as: 或者,如果可以更改func的参数顺序以接收next回调作为第一个参数,则它可能很简单:

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

demo: http://jsbin.com/ucUZUBe/1/edit?js,console 演示: http : //jsbin.com/ucUZUBe/1/edit?js,控制台

Thanx, @Herms. 谢谢,@赫姆斯。 Working solution: 工作解决方案:

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

You can loop through the array 您可以遍历数组

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM