JS中如何解决for循环中的延迟执行问题

JavaScript018

JS中如何解决for循环中的延迟执行问题,第1张

我们先来看一个例子

在JS方法里面设置一个for循环,输出每次循环的值,如下图

我们可以根据闭包的知识来更改一下for循环中的逻辑,利用闭包将i的值传递给a

这次在运行程序我们就可以看到输出内容是0开始输出了

结果如下图

JS中如果for循环中有异步方法,就需要用闭包的方式保留当前循环变量值

学习记录,别提问,我可能答不上来!^-^。。。

1.预编译

我们的需求是希望输出0-9 依次输出 0 1 2 3 4 5 6 7 8 9 ,但是这个输出的是十个10;

为什么是十个10呢,因为test()函数内循环时,arr[i]是被赋值为一个函数体,该函数体并没有执行,所以console.log(i)中的i并没有随着arr[i]中的i一起改变,然后被保存到外部myArr,myArr就是一个数组,里面有10个函数,myArr[j]()就是来调用myArr中的函数运行。当myArr[j]()函数运行console.log(i)时,这个i访问的是test()的AO。

上文说到arr[i]并没有运行,test()中for循环i=10时不满足循环条件,退出循环,这时 test()的AO对象中i就等于10了,在test()函数结束之前,arr被返回到函数外部,这个myArr就继承了test() 的AO对象。至此test()执行完毕,释放AO对象。重点来了,test()的AO 对象释放了,但是!myArr在test()结束之前继承了test()的AO对象,所以test()的AO对象被myArr拿到了手中,没想到吧!!所以在myArr循环输出console.log(i)时,这个i实际输出的是test()AO中的i,这个i在test()循环结束时等于10,所以外部循环调用输出console.log(i),循环10次,输出的就是10个10。好晕!看图:

匿名函数自调会立即执行,让i作为实参,j为形参,函数声明执行前都会预编译生成AO, 形参实参统一,每执行一次形参j都会跟实参 i 改变;循环结束后arr中就相当于放了10个匿名函数自调,并引用了匿名函数自调的AO,每一个AO中j都根据i而累加了,所以在外部调用输出j时,就再这个匿名函数自调中找j,输出就达到我们要的效果啦。下图是arr中匿名函数的AO,每一个j都根据i改变:

至此就完美的解决闭包问题啦!!

学习记录,有写错的地方可以指出改正^-^