是否保证foreach(Array.prototype.forEach
)每次都在相同数据集上以相同顺序循环?为什么呢?
答案 0 :(得分:1)
如果实现遵循标准,则是,forEach
按顺序处理数组,但稀疏数组除外,在稀疏数组中会忽略未初始化的值。 the spec中描述了forEach()
:
forEach为数组中存在的每个元素按升序调用一次callbackfn。仅对实际存在的数组元素调用callbackfn。不会因为缺少数组元素而调用它。
它从以下位置开始遍历索引:
让lenValue是使用参数“ length”调用O的[[Get]]内部方法的结果 设k为0。
重复,而k...
将k增加1
在javascript数组中是对象,它们具有length
属性和作为索引的整数键。规范说它将从k=0
开始,并以arr[k]
的升序调用k < length
。它将为arr
具有属性k
forEach
忽略元素的稀疏数组的示例可能如下所示:
let a = Array(10)
a[5] = "Five"
a[9] = "Nine"
console.log(a)
// ignores initialized values:
a.forEach((item) => console.log(item))
如果您在回调内部执行异步操作,则可能看起来回调没有按顺序进行,但仍然按顺序进行。
基于评论的编辑:
您可以通过一点黑客操作将看起来像数组的对象传递给forEach
(它具有长度和整数键)。 forEach
将按照 index 的顺序调用项目,而不是在对象上定义的顺序。例如:
// an object that has enough info
// for forEach to use
let o = {
3: "three",
2: "two",
0: "zero",
1: "one",
length: 4
}
// calls in order of indexes, not order keys were defined
Array.prototype.forEach.call( o, (i) => console.log(i))
答案 1 :(得分:1)
是的,forEach将等待上一项完成,然后再处理下一项
//Sync methods;
[1,2,3].forEach(function(e){
console.log(e)
});
//Output:
//1
//2
//3
如果您在循环内使用 Async方法,则会依次调用它们,但循环将不等待回调。
//Async Methods
[1,2,3].forEach(function(e){
someAsyncMethod(e, console.log);
});
//Output example:
//3
//1
//2
此answer有一些方法可以在foreach中使用异步函数。
关于为什么的问题,有一个名为 ECMAScript 的国际标准,所有JavaScript实现都应遵循该标准; Array.prototype.forEach()
的行为已在此标准中指定。
您可以在ECMAScript® 2018 Language Specification处找到Array.prototype.forEach()
的规范和伪代码