• ES6.--Promise、任务队列和事件循环


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    1.promise概述

    (1)promise是异步编程的一种解决方案。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

    (2)Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。

    (3)Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。

    (4)Promise是一个构造函数,其原型上有then、catch方法,对象上有reject、resolve方法。

    (1)同步、异步的设计思想

    同步、异步的概念

            同步:按照一定的顺序去执行,执行完一个才能执行下一个
            异步:执行顺序是不确定的,由触发条件决定,什么时间执行也是不确定的,即使是定时器(下面做解释),异步处理可以同时执行多个。

    通过代码理解:

    同步代码的书写顺序和代码的执行顺序一样

    异步代码的书写顺序和代码的执行顺序不一样

    阻塞:在等待结果的过程中,不能干其他事,线程被挂起,直到结果返回。

    非阻塞:在等待结果的过程中,还能干其他事,线程不会被阻塞。

            同步和异步的区别:同步是按照执行顺序一步一步往下执行的,异步是按照代码执行顺序的时候,可以去执行其他的,不按照顺序来的,执行的顺序是不确定的。

    同步的设计思想

    1. function createData(){
    2. return parseInt((Math.random()*(90-50)+50))
    3. }
    4. var obj={
    5. data:100,
    6. tool:function(){
    7. var data=createData()
    8. this.data=data
    9. }
    10. }
    11. obj.tool()
    12. console.log(obj.data)

    运行结果:

    异步的设计思想-回调函数

    1. function createData(callback) {
    2. callback(parseInt((Math.random() * (90 - 50) + 50)))
    3. }
    4. var obj = {
    5. data: 100,
    6. tool: function() {
    7. var a = 20;
    8. createData((n) => {
    9. this.data = n
    10. })
    11. var b=100;
    12. for(;;){}
    13. }
    14. }
    15. obj.tool()
    16. console.log(obj.data)

    1. function fn (cb,n) {
    2. for(var i=0;i
    3. cb()
    4. }
    5. //异步函数
    6. console.log(1)
    7. fn(function(){console.log(3)},10000) //这个函数内部也有一个打印 3
    8. console.log(5)
    9. // fn函数不可能是异步函数 但是js的底层 c/c++是有不阻塞代码的异步函数的
    10. setTimeout(function(){console.log(4)},1000)
    11. console.log(2)
    1. function fn (cb,n) {
    2. for(var i=0;i
    3. cb()
    4. }
    5. //异步函数
    6. console.log(1)
    7. fn(function(){console.log(3)},10000) //fn阻塞,先执行完在执行输出5
    8. console.log(5)
    9. // fn函数不可能是异步函数 但是js的底层 c/c++是有不阻塞代码的异步函数的
    10. setTimeout(function(){console.log(4)},1000)
    11. console.log(2) //fn延迟了,所以先打印2在打印输出4

    运行结果:

    (2)阻塞异步

    同步阻塞:张三在用烧水壶烧开水,直到开水烧开。

    同步非阻塞:张三在用烧水壶烧开水的时候,就去做其他事情了。

    异步阻塞:张三在用晌水壶烧开水,直到开水烧开。

    异步非阻塞:张三在用晌水壶烧开水,就去做其他事情了。

    阻塞异步的例子:

            //阻塞异步

                       fn1(function(){console.log(1)})

            //官方提供的非阻塞异步函数

                       setTimeOut(function(){console.log(2)})

            //阻塞异步

                       fn3(function(){console.log(3)})

    (3)promise语法

     setTimeout()函数是一个非阻塞的异步函数

                setTimeout(()=>{console.log(11)},3000)

                setTimeout(()=>{console.log(22)},4000)

    后端的fs.readFile()函数也是一个非阻塞的异步函数

    es6 中的promise对象的then函数也是一个非阻塞的异步函数

    1.Promise是一个ES5已经出现了  ES6直接写入标准

    2.Promise是一个构造函数 创建了一个数据容器

        数据容器:map  set arr  object,它们是被动产生数据 给它添加数据

        Promise主动产生数据 不用给它添加数据  而是它自己产生数据     

    例如:   

    1.   var p1=new Promise(function(n1,n2){
    2.                 var n=Math.random()
    3.                 n1(n) //n1调用了 就代表p1产生了数据
    4.             })

    运行结果:

    (4)then()函数

    then函数是一个异步非阻塞函数

    then的规则:

        then函数的返回值是 一个新的promise对象

             是then传入的回调函数的返回值:

                 1.如果是一个promise对象 那么就是它

                 2.如果不是一个promise对象,那么就会把函数的结果包装为一个生成数据了的promise对象

    1. var p1=new Promise(function(n1,n2){
    2. var n=Math.random()
    3. n1(n) //n1调用了 就代表p1产生了数据
    4. })
    5. var re=p1.then(function(data){
    6. console.log(data,111)
    7. return 200
    8. })
    9. console.log(222)
    10. re.then((data)=>{console.log(data,333)})

    运行结果:

    程序举例:

    运行结果:

     

    2.任务队列和事件循环

    (1)异步编程中最难的  任务的队列分类  和事件循环

    (2)任务指的就是js代码中的运行的代码

    (3)fn() 代表了fn任务的运行 ,脚本也是一个任务,计时器的运行也是一个任务,promise也是一个任务

    (4)任务分为同步的任务 和异步的任务

    同步任务:同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。

    异步任务:异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。

    事件循环

    同步任务举例:

                function fn(){}

                var a=new Array()

                var b=fn()

    异步任务举例:

                setTimeout(fn,1000)

                p1.then(fn)

                console.log(123)

    程序举例:

    1. console.log(4)
    2. setTimeout(() => {
    3. setTimeout(()=>{console.log(6)},0)
    4. console.log(1)
    5. var p2 = new Promise((n1, n2) => {
    6. n1(1000)
    7. })
    8. p2.then(()=>{console.log(7)})
    9. }, 0)
    10. setTimeout(() => {
    11. setTimeout(() => {console.log(2)}, 200)
    12. var p3 = new Promise((n1, n2) => {
    13. n1(1000)
    14. })
    15. p3.then(()=>{console.log(8)})
    16. console.log(2)
    17. }, 0)
    18. var p1 = new Promise((n1, n2) => {
    19. n1(1000)
    20. })
    21. p1.then(() => {console.log(3)})
    22. console.log(5)

    运行结果:

    异步任务的队列优先级: 异步宏任务先执行 然后在执行异步微任务

            事件循环

            任务开启后:内部执行的时候可能会有新的任务

                1. 先执行同步任务

                2.添加新的宏任务到队列中 添加新的的异步微任务

                3.执行异步微任务

    那些属于宏任务:   

            宏:脚本就是一个宏任务  

            脚本运行 执行第一个宏任务:

  • 相关阅读:
    JSP 语法简介说明
    Linux电话本的编写-shell脚本编写
    JSP 标准标签库(JSTL)
    C. Yarik and Array Codeforces Round 909 (Div. 3) 1899C
    Python trino执行hive insert overwrite不生效的问题
    k8s etcd 简介
    区间预测 | Matlab实现CNN-ABKDE卷积神经网络自适应带宽核密度估计多变量回归区间预测
    BERT论文精读
    mysql常用函数归纳(简单)
    Linux打包和使用动静态库
  • 原文地址:https://blog.csdn.net/m0_63774574/article/details/125766102