异步编程

同步模式
我们的代码从上往下依次执行,后面的代码必须等前面的代码执行完毕才能执行。
看下面这张图,你们觉得执行的顺序应该是怎样的?

很显然,执行顺序是
global begin
foo task
bar task
global end

那么,问题来了,这种后面的代码必须等前面的代码执行完毕才能继续执行的排队执行的机制也存在着一个问题,如果前面是一个特别耗时,浪费性能的任务,那么会将浏览器挂起,这种挂起对于用户来说会造成程序阻塞或者卡死,所以就由异步操作去解决程序中那些无法避免的耗时操作,例如,ajax ,大文件

异步模式
不同于同步的执行方式,异步不会等待这个任务结束才去执行下一个任务,对于耗时操作,它都是开启之后就执行下一个任务。那耗时任务的后续逻辑我们会通过回调函数的方式去定义。看下面这张图的执行顺序应该是怎样的?

1、在主线程中console.log('global begin')先进行压栈,执行打印,打印完后弹栈

2、接着往下执行setTimeout(timer1)进行压栈,因为内部是异步调用,所以放到了异步线程执行,不会影响主线程,调用完成,然后弹栈

3、接着往下执行setTimeout(timer2)进行压栈,开启另一个倒计时,进行弹栈

4、接着往下执行console.log('global end')进行压栈,执行打印,打印完后弹栈

5、接着往下执行主线程同步任务执行完后,事件循环会从任务队列中取出第一个回调函数然后压入到调用栈中,现在任务队列中现有timer1() 1.8s timer2()1s,也就是将timer2()1s压入到主线程调用栈中这其中又遇到了异步操作,同样,先放到异步线程进行倒计时,调用完成,弹栈。

6、接着往下执行事件循环会从任务队列中取出timer1(),先进行压栈,执行打印,打印完后弹栈

7、最后。任务队列只剩下inner异步操作,事件循环会从任务队列中取出inner进行压栈,执行打印,最后弹栈

所以,最后的结果是:
global begin
global end
timer2 invoke
timer1 invoke
inner invoke

你可能感兴趣的:(异步编程)