JavaScript 进阶营

JavaScript中代码执行顺序问题

2019-11-13  本文已影响0人  gis11

一. 问题背景

      在我们编写js代码时,有时会遇到这样的问题:循环执行内部异步请求函数,将得到的值加入到列表中。 结果出人意料,console.log显示列表值竟然为空,这是js的一大特性,与我们平时用的后端语言java C#  python等区别略大。 导致问题的根本所在就是线程问题,JS是单线程的,而后端语言是多线程的。

    表象来讲,单线程:同一个时间只能做一件事。多线程:同一时间,可以做多件事。

    js的单线程并不是说只有一个线程,而是执行代码的线程只有一个,称为主线程。那么当初为什么设计成单线程呢,这也与B/S交互问题有关,如果是多线程会出现交互混乱。

二.同步和异步

    回顾问题,我们看到执行中有异步请求函数,与之对应的是同步。同步和异步的区别简单来说就是,比如 我们要计算一个值,同步就是等计算完这个值我才能继续执行下边的代码; 而异步就是我先不等他,我继续执行,放一个闹铃,计算完成后提醒我完成了,然后我再插一脚执行对计算值的处理函数。

三.任务队列

    js单线程问题,也就是说执行要按顺序来,那么是什么顺序呢,这就提到另一个东西,叫任务队列,队列即先进先出表,也就是排队的地方,那么具体怎么排呢 , 执行机制是这样的: 主线程会优先执行同步任务,异步任务得到请求后的处理事件进入任务队列,需要注意的是异步完成后也并不是立即执行,而是等到主线程把同步任务执行完,再按异步的排队顺序,执行异步的回调处理。而我们问题的所在就是console.log属于同步任务,也就是说异步请求的列表值还没添上呢就执行了console.log。

四.解决方法

  常见解决方法就是构造回调函数, 最常用的方式就是BOM中的定时器函数,这个函数也很特殊,他是属于另一个线程操作的,也就是说设定时间到达之后,才把console.log设为同步任务为主线程执行,那么当设定一段时间后,异步也执行完了,此时也就有了结果。

  我自己使用过程中,发现这个问题在请求函数的回调中,设计判断函数,比如列表长度等于 自己需要的长度时再console.log,也能解决问题,这种就属于特定问题特定解决了,更通用的方法还是构造自定义回调函数。

  对于现在的js es还有很多方式,无一例外就是构造回调,自行百度其他方法

上一篇 下一篇

猜你喜欢

热点阅读