zoukankan      html  css  js  c++  java
  • promise.then, setTimeout,await执行顺序问题

    •  promise.then VS setTimeout

      在chrome和node环境环境中均输出2, 3, 1, 先输出2没什么好说的,3和1顺序让人有些意外

    原因

    有一个事件循环,但是任务队列可以有多个。

    整个script代码,放在了macrotask queue中,setTimeout也放入macrotask queue。

    但是,promise.then放到了另一个任务队列microtask queue中。

    这两个任务队列执行顺序如下,取1个macrotask queue中的task,执行之。

    然后把所有microtask queue顺序执行完,再取macrotask queue中的下一个任务。

    代码开始执行时,所有这些代码在macrotask queue中,取出来执行之。

    后面遇到了setTimeout,又加入到macrotask queue中,

    然后,遇到了promise.then,放入到了另一个队列microtask queue。

    等整个execution context stack执行完后,

    下一步该取的是microtask queue中的任务了。

    因此promise.then的回调比setTimeout先执行。

    • await

    async function a() {
        await console.log(1)
        console.log(2)
    }
    
    async function b() {
        await a();
    }
    
    b();
    
    console.log(3)

    输出: 1, 3, 2

    async function a() {
        await console.log(1)
        console.log(2)
    }
    
    async function b() {
        await a();
    }
    
    b();
    
    setTimeont(function(){console.log(3)},0)
    输出: 1,  2, 3

    await不会造成程序阻塞,只是promise的语法糖,可以看看babel编译后async/await, 可以这么理解,async 是多个异步操作的promise对象,await相当于then,代码执行跟你用callback写的代码并没有什么区别,本质上并不是同步代码,只是让你思考代码逻辑的时候能够以同步的思维去思考,避开回调地狱,要理解异步,首先要理解cpu的工作方式,cpu执行代码的时候,一个周期是以时间片为单位,实际上,无论是php还是node,处理同一个请求,cpu需要的计算量是一样的,在同样的时间内,cpu能做的计算量是一样的,差别在于,node只是提高了cpu的利用率。从而提高了同一时间能处理的请求数量。
     
    打个比方,你去银行办理业务,只有一个窗口在办理业务(一个cpu进程),假设有两个人(A和B)要办理银行卡(可理解为一次请求),方式一:A到窗口前,但这个时候要办卡的话,柜员告诉你,要你的身份证复印件(可理解为IO操作),这个时候,你去复印,柜员等待,回来后继续办理,A办理完成后,B接着同样的步骤。方式二:在A去复印身份证的时候,柜员受理B的办理请求, 等A回来后再受理A的业务。所以,很明显,方式二在同样多的时间内,一个窗口能办理的银行卡数量更多,因为这种方式充分利用了柜员等待的时间,那么方式一就是php处理请求的方式,在PHP中,处理IO操作的时候(比如,访问数据库,读取文件等),实际上cpu是处于等待状态,但其他资源此时得不到cpu的计算资源,属于资源浪费,cpu并没有接受下一个请求,而方式二,则是node处理的方式。所以综上所述,async/await 并不会影响node的并发数量,async/await是以同步的思维去写异步的代码。

  • 相关阅读:
    如何快速搞定websocket
    websocket断网消息补发
    div嵌套多个点击事件,点击后如何阻止多次事件触发冒泡
    仿照 MediatR实现了一个中介者模式Publish功能,使用同MediatR
    git提交指南(超级详细)
    删除github中的文件夹
    抽取进程集成模式注册报错,OGG-08221,OCI Error ORA-44004 invalid qualified SQL Name
    Oracle-参数学习_no_or_expansion
    OGG19版本源端新增字段,目标端复制进程不报错,使用MAPALLCOLUMNS进行测试
    Oracle存储过程如何定位慢SQL?
  • 原文地址:https://www.cnblogs.com/billyu/p/9211292.html
Copyright © 2011-2022 走看看