Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在阵列(或OBJ)上迭代异步的最聪明/最干净的方法是什么?_Javascript_Node.js - Fatal编程技术网

Javascript 在阵列(或OBJ)上迭代异步的最聪明/最干净的方法是什么?

Javascript 在阵列(或OBJ)上迭代异步的最聪明/最干净的方法是什么?,javascript,node.js,Javascript,Node.js,我就是这样做的: function processArray(array, index, callback) { processItem(array[index], function(){ if(++index === array.length) { callback(); return; } processArray(array, index, callback); }); };

我就是这样做的:

function processArray(array, index, callback) {
    processItem(array[index], function(){
        if(++index === array.length) {
            callback();
            return;
        }
        processArray(array, index, callback);
    });
};

function processItem(item, callback) {
    // do some ajax (browser) or request (node) stuff here

    // when done
    callback();
}

var arr = ["url1", "url2", "url3"];

processArray(arr, 0, function(){
    console.log("done");
});
有什么好处吗?如何避免那些意大利面条式的代码

签出该库,它是为控制流(异步内容)而设计的,并且它有很多用于数组内容的方法:each、filter、map。查看github上的文档。以下是您可能需要的:

每个(arr、迭代器、回调)

将迭代器函数并行应用于数组中的每个项。迭代器由列表中的一个项和完成时的回调调用。如果迭代器将错误传递给此回调,则会立即调用
每个
函数的主回调并显示错误

每个系列(arr、迭代器、回调)

每个
相同,仅迭代器应用于串联数组中的每个项。下一个迭代器仅在当前迭代器完成处理后调用。这意味着迭代器函数将按顺序完成。

签出库,它是为控制流(异步内容)而设计的,并且它有许多用于数组内容的方法:each、filter、map。查看github上的文档。以下是您可能需要的:

每个(arr、迭代器、回调)

将迭代器函数并行应用于数组中的每个项。迭代器由列表中的一个项和完成时的回调调用。如果迭代器将错误传递给此回调,则会立即调用
每个
函数的主回调并显示错误

每个系列(arr、迭代器、回调)


每个
相同,仅迭代器应用于串联数组中的每个项。下一个迭代器仅在当前迭代器完成处理后调用。这意味着迭代器函数将按顺序完成。

正如正确指出的,您必须使用setTimeout,例如:

each_async = function(ary, fn) {
    var i = 0;
    -function() {
        fn(ary[i]);
        if (++i < ary.length)
            setTimeout(arguments.callee, 0)
    }()
}


each_async([1,2,3,4], function(p) { console.log(p) })
each_async=函数(ary,fn){
var i=0;
-函数(){
fn(ari[i]);
if(++i
正如正确指出的,您必须使用setTimeout,例如:

each_async = function(ary, fn) {
    var i = 0;
    -function() {
        fn(ary[i]);
        if (++i < ary.length)
            setTimeout(arguments.callee, 0)
    }()
}


each_async([1,2,3,4], function(p) { console.log(p) })
each_async=函数(ary,fn){
var i=0;
-函数(){
fn(ari[i]);
if(++i
正如某些答案所指出的,可以使用“异步”库。但有时您只是不想在代码中引入新的依赖项。下面是另一种方法,可以循环并等待一些异步函数的完成

var items = ["one", "two", "three"];

// This is your async function, which may perform call to your database or
// whatever...
function someAsyncFunc(arg, cb) {
    setTimeout(function () {
        cb(arg.toUpperCase());
    }, 3000);
}

// cb will be called when each item from arr has been processed and all
// results are available.
function eachAsync(arr, func, cb) {
    var doneCounter = 0,
        results = [];
    arr.forEach(function (item) {
        func(item, function (res) {
            doneCounter += 1;
            results.push(res);
            if (doneCounter === arr.length) {
                cb(results);
            }
        });
    });
}

eachAsync(items, someAsyncFunc, console.log);

现在,运行
节点iterasync.js
将等待大约三秒钟,然后打印
['1','2','3']
。这是一个简单的例子,但它可以扩展到处理许多情况。

正如一些答案中所指出的,可以使用“异步”库。但有时您只是不想在代码中引入新的依赖项。下面是另一种方法,可以循环并等待一些异步函数的完成

var items = ["one", "two", "three"];

// This is your async function, which may perform call to your database or
// whatever...
function someAsyncFunc(arg, cb) {
    setTimeout(function () {
        cb(arg.toUpperCase());
    }, 3000);
}

// cb will be called when each item from arr has been processed and all
// results are available.
function eachAsync(arr, func, cb) {
    var doneCounter = 0,
        results = [];
    arr.forEach(function (item) {
        func(item, function (res) {
            doneCounter += 1;
            results.push(res);
            if (doneCounter === arr.length) {
                cb(results);
            }
        });
    });
}

eachAsync(items, someAsyncFunc, console.log);

现在,运行
节点iterasync.js
将等待大约三秒钟,然后打印
['1','2','3']
。这是一个简单的示例,但可以扩展到处理许多情况。

处理数组(或任何其他iterable)的异步迭代的最简单方法是使用wait运算符(仅在异步函数中)和for of循环

(异步函数(){
for(让[0,1]的值){
值+=等待(承诺.解决(1))
console.log(值)
}

})()
处理数组(或任何其他iterable)的异步迭代的最简单方法是使用wait操作符(仅在异步函数中)和for of循环

(异步函数(){
for(让[0,1]的值){
值+=等待(承诺.解决(1))
console.log(值)
}

})()
在现代JavaScript中,有一些有趣的方法可以将数组扩展为异步itarable对象

在这里,我想展示一个全新类型
AsyncArray
的框架,它继承了
Array
类型的优点,将其扩展为一个asyncIterable数组

这仅适用于现代发动机。下面的代码使用了最新的技巧,如和

如果您不熟悉这些主题,我建议您提前查看上述链接主题

class AsyncArray extends Array {
  #INDEX;
  constructor(...ps){
    super(...ps);
    if (this.some(p => p.constructor !== Promise)) {
      throw "All AsyncArray items must be a Promise";
    }
  }
  [Symbol.asyncIterator]() {
    this.#INDEX = 0;
    return this;
  };
  next() {
    return this.#INDEX < this.length ? this[this.#INDEX++].then(v => ({value: v, done: false}))
                                     : Promise.resolve({done: true});
  };
};

在现代JavaScript中,有一些有趣的方法可以将数组扩展为异步itarable对象

在这里,我想展示一个全新类型
AsyncArray
的框架,它继承了
Array
类型的优点,将其扩展为一个asyncIterable数组

这仅适用于现代发动机。下面的代码使用了最新的技巧,如和

如果您不熟悉这些主题,我建议您提前查看上述链接主题

class AsyncArray extends Array {
  #INDEX;
  constructor(...ps){
    super(...ps);
    if (this.some(p => p.constructor !== Promise)) {
      throw "All AsyncArray items must be a Promise";
    }
  }
  [Symbol.asyncIterator]() {
    this.#INDEX = 0;
    return this;
  };
  next() {
    return this.#INDEX < this.length ? this[this.#INDEX++].then(v => ({value: v, done: false}))
                                     : Promise.resolve({done: true});
  };
};

使用jQuery,可以使用
$.each([…],function(){…})$.each([…],function(){…})函数()
之前有一个“-”(减号)?@AaronDigulla
-function()
导致立即数函数被视为一个表达式。它实际上与将函数包装在括号中没有任何区别,这是使其成为有效表达式的另一种方法。请参阅:为什么se前面有一个“-”(减号)