【JavaScript】JavaScript同步、异步、回调的执行顺序

来源:互联网 发布:什么是行知教育思想 编辑:程序博客网 时间:2024/05/21 06:36

口诀:同步优先、异步靠边、回调垫底(同步=>异步=>回调)

有一道经典的面试题:

for (var i = 0; i < 5; i++) {    setTimeout(function() {        console.log('i: ',i);    }, 1000);}console.log(i);//输出5i:  5i:  5i:  5i:  5i:  5

为什么最先输出的是5呢?
  for循环先执行,但是不会给setTimeout传参(回调垫底),等for循环执行完,就会给setTimeout传参,而外部的console.log打印出5是因为for循环执行完了。

为什么setTimeout输出5个5呢?
  这里涉及到JavaScript 执行栈 和 消息队列 的概念。
  JavaScript同步的代码是在堆栈中顺序执行的,而setTimeout相当于写了一个异步的方法,放在消息队列中。for循环每执行一次,就会放一个setTimeout到消息队列排队等候,当同步的代码执行完了,再去调用消息队列的回调方法。
  for循环结束之后,因为i是用var定义的,所以var是全局变量,这个时候的i是5,那么当执行setTimeout的时候,由于全局变量的i已经是5了,所以传入setTimeout中的每个参数都是5。(很多人误以为setTimeout里面的i是for循环过程中的i,这种理解是不对的)


再来个类似的例子加深理解~

for (var i = 0; i < 5; ++i) {    setTimeout(function() {        console.log('2: ',i);    }, 1000);    console.log('1: ', i); //新加一行代码}console.log(i);//输出1:  01:  11:  21:  31:  452:  52:  52:  52:  52:  5

  这个例子可以清楚的看到先执行for循环,for循环里面的console.log是同步的,所以先输出;for循环结束后,执行外部的console.log输出5;最后执行setTimeout回调。

原创粉丝点击