frontend-interview icon indicating copy to clipboard operation
frontend-interview copied to clipboard

解释一下JS中的异步IO、回调、Eventloop

Open su37josephxia opened this issue 3 years ago • 18 comments

su37josephxia avatar Feb 13 '22 00:02 su37josephxia

什么是异步 IO 从 API 上来说,它是一组非阻塞的 IO API 什么是回调 回调就是一个函数的调用过程,函数 a 有一个参数,这个参数是个函数 b,当函数 a 执行完以后执行函数 b,那这个过程就叫回调。 什么是 Eventloop

  • JS 引擎线程会维护一个执行栈,同步代码会依次加入到执行栈中执行并出栈;
  • JS 引擎线程遇到异步函数,会将异步函数交给相应的 Webapi,而继续执行后面的任务;
  • Webapi 会在条件满足的时候,将异步对应的回调加入消息队列中,等待执行;
  • 当执行栈为空时,JS 引擎线程会去取消息队列中的回调函数(如果有的话),并加入执行栈中执行;
  • 完成后出栈,执行栈再次为空,重复上面的操作。

QbjGKNick avatar Feb 13 '22 13:02 QbjGKNick

异步 io 就是做 io 操作的时候不等待结果,而是让结果完成后进行通知。

回调是稍后执行的函数,通过传递回调函数给 eventloop,程序等待适合的时机调用回调。

eventloop 是事件循环,在另一个线程会一直进行轮询,将存储的要执行的回调派发出去。

回调是同步代码,只是什么时候推入函数执行栈,由eventloop决定。如果是自己控制的回调,则取决于自己的代码什么时候执行这个回调。

zcma11 avatar Feb 13 '22 14:02 zcma11

什么是异步 IO 从 API 上来说,它是一组非阻塞的 IO API 什么是回调 回调就是一个函数的调用过程,函数 a 有一个参数,这个参数是个函数 b,当函数 a 执行完以后执行函数 b,那这个过程就叫回调。 什么是 Eventloop javascript异步。从最早接触到的 setTimeout,setInterval,callback再到后来的Promise,async, node的setImmediate,process.nextTick等等。 setTimeout(()=>{ console.log('timer1')

Promise.resolve().then(function() {
    console.log('promise1')
})

}, 0)

setTimeout(()=>{ console.log('timer2')

Promise.resolve().then(function() {
    console.log('promise2')
})

}, 0)

674252256 avatar Feb 13 '22 14:02 674252256

js任务分两种,一种是同步任务(synchronous),一种是异步任务(asynchronous)

  • 同步任务是指在主线程上排队的任务,只有前一个任务执行完毕,才会执行后面的任务。
  • 异步任务是指不进入主线程,而是进入任务队列(task queue),当任务队列通知主线程某一个异步任务可以执行的时候,才会进入主线程执行。
  • 主线程从任务队列中读取事件,这个过程是不断循环的,称为EventLoop(事件循环)

chunhuigao avatar Feb 13 '22 14:02 chunhuigao

异步IO就是非阻塞IO,当有异步方法时,不阻塞主线程,可以继续执行主线程任务 回调就是将函数传递给异步方法,由异步方法来决定什么时候调用 eventloop事件循环,是一种运行机制,他会轮询主线程的任务是否执行完毕,如果执行完就执行异步任务

yaoqq632319345 avatar Feb 13 '22 14:02 yaoqq632319345

https://juejin.cn/post/7064199923004080159/

Limeijuan avatar Feb 13 '22 14:02 Limeijuan

  • 异步IO:是一组非阻塞的IO API,程序不因为IO调用而被阻塞,就可以说程序是异步的。
  • 回调:回调函数是一个作为变量传递给另外一个函数的函数,它在主体函数执行完之后执行。
  • Eventloop:
  1. 开始,任务先进入 Call Stack
  2. 同步任务直接在栈中等待被执行,异步任务从 Call Stack 移入到 Event Table 注册
  3. 当对应的事件触发(或延迟到指定时间),Event Table 会将事件回调函数移入 Event Queue 等待
  4. 当 Call Stack 中没有任务,就从 Event Queue 中拿出一个任务放入 Call Stack

wzl624 avatar Feb 13 '22 15:02 wzl624

异步 IO 简单来说就是一组非阻塞的 IO API。 回调就是回调函数,一个函数的其中一个参数也是一个函数并在某一时刻会被执行这就是回调函数。 Event Loop即事件循环,是一个事件执行模型,是 JS 实现异步的具体解决方案,所以 JS 虽然无法进行多线程操作,但可以通过异步的方式模拟多线程的操作。

alec1815 avatar Feb 13 '22 15:02 alec1815

  • 异步IO:简单来说就是一组非阻塞的 IO API。
  • 回调:回调就是一个回调函数,回调函数作为变量传给另外一个函数,这个函数会在某个时刻执行,也就是通常说的callback
  • event loop:就是事件循环,JS实现异步的解决方案,因为js是单线程的,无法进行多线程操作(常规情况下),但是可以通异步的方式模拟多线程

792472461 avatar Feb 13 '22 15:02 792472461

异步IO:

简单来说就是后面的任务执行不依赖前一步异步函数调用的结果,前一步函数的执行不会阻塞后面的任务

回调:

回调是指依赖另外一个函数执行完成之后调用的函数,即回调函数的调用时机取决于调用它的函数的执行的是否完成

evetloop:

Javavscript是单线程执行任务,主线程遇到同步任务回直接执行,遇到异步任务,会去event table注册回调函数,回调函数满足触发条件了,Js引擎会把回调函数从event table压入event queue,主线程同步任务执行完了,就会从event queue读取回调函数执行,这样一个只要主线程任务为空就去event queue读取回调任务的过程称为eventloop;

guoshukun1994 avatar Feb 13 '22 15:02 guoshukun1994

聊聊异步IO/回调/eventloop


浏览器的每个tab都有一个渲染进程,渲染进程都有一个主线程,而且主线程非常忙,要处理dom/要计算样式/还要处理布局,同时还要处理javascript任务各种输入事件。要让这么多不同类型的任务在主线程有条不絮地执行,就需要一个系统来统筹调度这些任务,这个统筹调度系统就是消息队列事件循环系统(event loop), 事件循环就例如一个while,不断的判断消息队列中是否有任务,有则执行,没有则挂起等待。


象如果我们执行一些IO操作,例如文件读取等,tab的IO线程会去处理文件的读取(因浏览器安全机制其实是浏览器进程将读取结果通过IPC传输给IO线程),当tab的IO线程完成IO读取后,会将IO操作的回调放入到消息队列中排队等待执行(消息队列按照优先级分为不同消息队列,例如宏任务队列,微任务队列),最后事件执行IO操作的回调任务。

jiafei-cat avatar Feb 13 '22 15:02 jiafei-cat

  • 异步IO

    IO设备事件一般指读取文件或网络请求等耗时任务,此时通常是执行异步任务。异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行

  • 回调

    回调就是异步任务的回调函数啊。所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

  • Eventloop

    主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。

    • MacroTask(宏任务)

      script全部代码、setTimeoutsetIntervalsetImmediateI/OUI Rendering

    • MicroTask(微任务)

      Process.nextTick(Node独有)Promise

    • 执行顺序

      • 执行js整体代码(宏任务)
      • 遇到setTimeout等,创建setTimeout等的回调函数(宏任务)到"任务队列"
      • 遇到Promise.then等,创建Promise.then等的回调函数(微任务)
      • 执行js整体代码(宏任务)执行完,执行当前所有微任务
      • 浏览器渲染
      • 渲染完,js执行下一个宏任务(从事件队列中获取可执行的宏任务)

superjunjin avatar Feb 13 '22 15:02 superjunjin

异步IO: 异步IO的概念和同步IO相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。 异步IO是单线程执行,遇到IO不阻塞,继续执行,IO执行完了会通知该线程,线程会在某个特定的时候处理IO返回的结果。 回调: 当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数

Eventloop:

js任务分两种,一种是同步任务(synchronous),一种是异步任务(asynchronous)

  • 同步任务是指在主线程上排队的任务,只有前一个任务执行完毕,才会执行后面的任务。
  • 异步任务是指不进入主线程,而是进入任务队列(task queue),当任务队列通知主线程某一个异步任务可以执行的时候,才会进入主线程执行。
  • 主线程从任务队列中读取事件,这个过程是不断循环的,称为EventLoop(事件循环)

BambooSword avatar Feb 13 '22 15:02 BambooSword

异步IO又叫非阻塞IO,是指进行IO操作的时候,程序在等待IO结果的时候可以同时进行其他的操作,而IO结果返回的时候会调用回调函数处理相应的逻辑。
回调函数是指当一个异步任务结束后调用的函数,通常作为异步任务的一个参数传入。
Eventloop 是事件循环。
因为 JavaScript 是单线程,所以同时只能做一件事,那如果前面的任务没有执行完成,后面来了新任务怎么办呢?
这个时候就引出了 Eventloop,JavaScript 会维护一个执行栈,栈中是所有待处理的任务,JavaScript 每次执行完当前任务就会去执行栈中查看是否还有待处理的任务,如果有,则会取栈顶任务执行,当栈中任务清空,会去查看微任务队列,如果有微任务,会清空微任务队列,然后查看宏任务队列,如果有宏任务,会取第一个宏任务放入执行栈执行,如此循环,就是 Eventloop。

zhenyuWang avatar Feb 13 '22 16:02 zhenyuWang

解释一下JS中的异步IO、回调、Eventloop ?

异步IO:异步 IO 是计算机操作系统对输入输出的一种处理方式 发起 I/O 请求的线程不等 I/O 操作完成,就继续执行后面的代码 I/O 结果用其他方式通知发起 I/O 请求的程序

回调:回调是一个可以作为参数传给另一个函数(高阶函数)执行的函数 回调函数有两种:同步和异步 同步回调是阻塞的 异步回调是非阻塞的

Eventloop:在一个事件循环中,异步事件返回结果后会被放到一个任务队列中 根据异步事件的类型,会被分到对应的宏任务队列或者微任务队列中 同一次事件循环中,微任务永远在宏任务之前执行 宏任务:setInterval()、 setTimeout() 微任务:new Promise()

ruixue0702 avatar Feb 13 '22 16:02 ruixue0702

异步IO

IO通常是指读取文件等操作,这些操作一般都是比较耗时的操作,如果等到文件读取完成再执行后面的代码,那么在进行 IO 操作的这段时间就会阻塞代码的执行,因此一般 IO 操作会使用异步的方式,使其不阻塞主线程代码的执行,等到 IO 操作完成后再通知到主线程继续执行

回调

回调一般是传递一个函数,然后让代码在执行到某个阶段的时候执行该函数,比如 ajax 请求,通常在发起请求之后就不会占用主线程了,等到接收到结果之后再利用回调继续完成后续的操作

Eventloop

JS 中有一个主线程和一个调用栈,所有的任务都需要加入到调用栈中执行,JS 中的单线程任务分为同步任务和异步任务,同步任务会按顺序添加到调用栈中等待主线程执行,而异步任务会等到结果返回之后加入到任务队列中,等到调用栈中的同步任务全都执行完之后,才会到任务队列中将异步任务读取到调用栈内等待主线程的执行

rachern avatar Feb 13 '22 16:02 rachern

异步IO 异步 io 就是做 io 操作的时候不等待结果,而是让结果完成后进行通知。 回调 回调是稍后执行的函数,通过传递回调函数给 eventloop,程序等待适合的时机调用回调。 Eventloop eventloop 是事件循环,在另一个线程会一直进行轮询,将存储的要执行的回调派发出去。

回调是同步代码,只是什么时候推入函数执行栈,由eventloop决定。如果是自己控制的回调,则取决于自己的代码什么时候执行这个回调。

partiallove avatar Feb 13 '22 17:02 partiallove

异步IO: 由于I/O操作很慢,所以这个JS线程的大部分运行时间都在空等I/O操作的返回结果。这种运行方式称为"同步模式"(synchronous I/O)或"堵塞模式"(blocking I/O)。

非阻塞IO: 也就是IO操作并不会阻塞主线程,所以提高了效率。

异步回调: 有很多情况的执行步骤(ajax请求远程数据,IO等)是非常耗时的,所以耗时的我们都扔给异步去做,做好了再通知下我们做完了,简单来说,就是异步完成后我们需要做的事情。

Event Loop 简单来说,Event Loop就是浏览器为了协调事件处理、脚本执⾏、网络请求和渲染等任务而制定的工作机制。先要明白什么是宏任务,微任务。

执行过程: 简单概括的来说就是下面的过程: ● Event Loop会不断循环的去取tasks队列的中最老的一个任务推入栈中执行, 并在当次循环里依次执行并清空microtask队列里的任务。 ● 执行完microtask队列里的所有的任务,有可能会渲染更新(如果有DOM变更的话)。 ● 执行下一个宏任务的时候,DOM已经重新渲染了。

zzunstu avatar Feb 14 '22 02:02 zzunstu