foreach难道真的只是for..of简简单单的语法糖吗?
作者:互联网
foreach的云云
问题引入
大佬们先看看两份代码以及执行结果,一份是使用原生for of,另一份是foreach。
这是在写异步操作的时候我遇到的一个问题,开始使用foreach的时候,结果总是不对,我没有给出来的处理代码里对于foreach遍历结果e的处理完全是错乱的,导致达不到预期目的。。。。
后来改成for of之后奇迹般的对了,,,这是个老坑了看提交记录应该是两个星期前的问题。。最近没什么时间研究,今天终于捡起来看看。
出现这种原因,首先我就想要去看foreach封装,我想出现差错的原因一定在于源码中的一些封装问题。
for (let item of array) {//
console.log("异步开始");
let res = await this.$service.xxx//这个xxx是指调用的接口服务
console.log("异步结束" + res);
//下面是其他一下处理代码就不放上来了
}
this.array.forEach(async (e) => {
console.log("异步开始");
let res = await this.$service.xxx;
console.log("异步结束" + res);
});
ok不废话了,开始分析。。。
官方解析:forEach的基础用法
可以看到forEach的两个参数,callbackfun(回调函数)以及thisArg。
callbackfun的三个参数分别是
- 数组当前项的值
- 数组当前项的索引
- 数组本身
举个例子来看一下:
var arr = [1, 2, 3, 4, 5];
arr.forEach(function (a, b, c, d) {
console.log(a);
console.log(b);
console.log(c);
});
运行结果:
好的了解了回调函数的参数之后,我们来看看thisArg是什么.
解释一下:如果我们调用forEach的时候提供了thisArg,那么它将作为回调callbackfn的this。如果说没有,那么就会被定义程undefined,此时的this就是全局了window。
依旧举个例子:
var array1 = ["a", "b", "c"];
var array2 = ["1", "2", "3"];
array1.forEach(function (value, index, arr) {
console.log(value, index, arr, this);
}, array2);
ok,到这里的话,就已经对于forEach的一些参数认知到了。接下来分析过程
回调分析
依旧是官方这边的过程分析
注意一个点:回调的执行。
注意回调是不会占用主线程的执行的,假设我们的回调函数是一个计时器,那么这个k值地自增依旧会继续下去,回调并不占用主线程地执行。也就是说,forEach内部实现地就是这么一个回调函数。
ok,讲到这里我们看前面地问题。我们在forEach内部使用了await了。await是什么,异步操作,本质上与回调是差不多地性质,都是在不干扰主线程地情况下运行着程序。那么问题来了。我在这个forEach相当于执行了两次回调函数。
this.array.forEach(async (e) => {
console.log("异步开始");
let res = await this.$service.xxx;
console.log("异步结束" + res);
});
这样的后果是什么。
我们知道for循环去执行一个遍历操作是飞快地。也就是在程序跑起来的一瞬间,几乎array这个数组内所有的回调函数都跑起来了,他们做的事情都是我现在写的这个await。当await函数结束了之后就会找到this.array.forEach这个线程中,将await异步得到的结果赋值给res重新执行后面的处理操作。
注意,上面这段分析中有两个重点:
- 几乎一瞬间所有的回调都跑起来了
- await结束,它的结果会自动找到主线程去赋值给res
既然如此,所有的这些回调都是一个函数,对于时间上的结束,他们的前后关系其实差异并不大。既然如此,res那里接受的返回值,就不仅仅是一个await的返回了。
我想这就是我那段代码出错的原因了。
反观for…of 人家就是一次循环一次大括号里的代码,说到底就是一个callbck的问题。
总结
所以说想要满足循环的条件下,又想用await,是不是用for…of会好一点。23333333
啊对于我这种英语废铁来说看那个英文语言规范简直要了我的命。。。创作不易啊,希望可以帮到大家,如果有什么问题,请及时指正!!
标签:console,log,..,res,await,简简单单,foreach,回调,forEach 来源: https://blog.csdn.net/m0_50546235/article/details/121872071