经朋友提醒,我写了一次我面试被问到的同异步问题

179 阅读2分钟

同步和异步

在我们平常处理一些业务逻辑的时候经常需要用到同步和异步去解决,尤其调了后端接口那一块常用。

首先我们先来理解一下这个同异步

定义:同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)。同步,就是调用某个东西是,调用方得等待这个调用返回结果才能继续往后执行。异步,和同步相反  调用方不会理解得到结果,而是在调用发出后调用者可用继续执行后续操作,被调用者通过状体来通知调用者,或者通过回掉函数来处理这个调用

举个例子:

你去商城买东西,你看上了一款手机,你和店家说买这一款手机,他就去仓库拿货,你得在店里等着,不能离开,这叫做同步。现在你买手机直接去京东下单,下单完成后你就可去做其他自己想做的事了,等货到了去签收就ok了.这就叫异步。

这里借用一下别人的图来更好的理解:

async.png

sync.png

dome
    console.log(1);//第一个console.log():1  ---》 以下console.log用数字代表
    setTimeout(function() {
            console.log(2);
    }, 0);
    new Promise(resolve => {
            console.log(3);
            resolve();
            console.log(4);
    })
    .then(() => {
        console.log(5);
        setTimeout(function() {
                console.log(7);
        }, 0);
    })
    setTimeout(function() {
            console.log(8);
    }, 0);
    console.log(6);

打印结果为:1 3 4 6 5 2 8 7

解释:首先JS为单线程,它会按顺序执行,不管同步异步,异步只是不等待执行结果。同步的任务没有优先级之分, 异步先执行微任务然后是宏任务,同等级下按代码顺序执行。

  • 微任务有:Promise , process.nextTick , MutationObserver ...等;
  • 宏任务有:setInterval , setTimeout , I/O ...等; 综上所述,得: 先打印出第一个console.log -->//1
    然后 2 进入事件循环队列 -->//打印还没执行完
    然后 3 -->//3 因为Promise只有.then | .catch | .finally 里面的才是异步的
    然后 4 -->//4
    然后 5 进入事件循环队列 -->//打印还没执行完
    然后 6 进入事件循环队列 -->//打印还没执行完
    然后 7 进入事件循环队列 -->//打印还没执行完
    然后 8 -->//6 然后事件队列的任务出栈进入主线程执行,首先2,5,6,7 在队列中2,6,7为宏任务,
    所以5先执行完-->//5
    接着看优先级,2和7处于同级别,6的级别更低一层,所以 2 -->//2
    然后 7 -->//8
    最后 6 -->//7

以上拙见若有误请您斧正。