JS中的异步和回调

2018-04-23  本文已影响0人  zhangyuwen

因为JavaScript是单线程执行的,意味着同一个时间点,只有一个任务在运行。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

同步:一定要等任务执行完了,得到结果,才执行下一个任务。

异步:不等任务执行完,直接执行下一个任务。

比如

fn1()
fn2()

fn1执行完才执行fn2。
异步:不等任务执行完,直接执行下一个任务。
如如

function f1(){
 setTimeout(function () {
    console.log(1)
 }, 1000);
}
function f2(){
    console.log(2)
}
f1()
f2()

这段代码就是就是异步,f2没有等f1执行完毕就执行了。
常见的异步有:
setTimeout、Ajax请求、dom事件,他们都属于在浏览器的webApi中。异步是通过浏览器实现的,浏览器为这些耗时任务开辟了另外的线程。

浏览器为他们开辟任务队列,然后把结果都放在callback queue。 v2-bda084269322ee343a478ac334e7a385_r.jpg

图片来自Philip Roberts的演讲《Help, I'm stuck in an event-loop》

回调(callback)

浏览器把异步的任务放在callback queue中,要想拿到必须使用回调(callback),当JS里的栈stack清空时,说明一个任务已经执行完了,这时就会从callback queue中寻找下一个人任务推入栈中(这个寻找的过程,叫做event loop,因为它总是循环的查找任务队列里是否还有任务)。
所以简单说,通过webApi创建异步任务。任务完成时,如果有指定了回调函数,将回调函数放入task queue中;如果没有指定回调函数,这个事件就被丢弃。回调函数:定义了异步任务完成时所要执行的操作,包括事件和定时器所指定的异步任务。
比如

function f1(callback){
 setTimeout(function () {
  console.log(1)
  callback();
 }, 1000);
}
function f2(){
    console.log(2)
}
f1(f2)

在1秒后f1执行结束,才会调用f2执行。

上一篇下一篇

猜你喜欢

热点阅读