• js的promise的究竟是同步还是异步的问题和promise.all可以同时请求多个接口是错误的回答的原因


    • 个人理解

    前景-代码输出结果是什么

    我们都知道,循环队列的时候,同步任务大于异步任务(异步任务里面的微任务又大于宏任务),那么你猜猜这个代码输出结果是 什么呢

    <script>
        setTimeout(() => {
        console.log(1);
    }, 0);
    
    new Promise(function(resolve,reject){
        console.log(2);
        resolve();
        console.log(3);
    }).then(function(){
        console.log(4);
    }).finally(function(){
        console.log(5);
    });
    console.log(6);
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 做出来了吗?我公布下答
    • 答案
    2 3 6 4 5 1 
    
    • 1

    前景解析

    • 首先,你知道同步>异步,可是可能不太会区分同步和异步,其实记住下面的异步任务就好,其他就都是同步任务了

    • 异步任务:setTimeout,setInterval,setImmediate(非标准),I/O,UI rendering,Promise

    • 你们肯定也知道,promise的优先级大于其他异步任务,因为Promise是微任务嘛

    • 但是呢,这里说promise是异步任务其实不完全对,因为创建promise的时候是同步执行的,nextTick才是异步执行的(也就是.then,.catch这种方法),下面的例子和前景例子很好的说明了这个情况

       new Promise(resolve=>{
            console.log(1);
            resolve(3);
        }).then(num=>{
            console.log(num);
        });
        console.log(2);
        //依次为 123
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    我们学习了上面的点,再来看看Promise.all方法

    • 在之前的时候,我一直想不明白,Promise.all方法为什么能做到将多个promise封装成为一个新的promise实例,并同步获取到结果,现在才知道原因,先看下面代码,后面再详细解释
      <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.1.3/axios.min.js"></script>
      <script>
        let work1 = new Promise((resolve,reject)=>{
          resolve(axios.get('https://api.oick.cn/dutang/api.php'))
        });
    
        let work2 = new Promise((resolve,reject)=>{
          resolve(axios.get('https://api.oick.cn/yiyan/api.php'))
        });
    
        let work3 = new Promise((resolve,reject)=>{
          resolve(axios.get('https://api.oick.cn/dog/api.php'))
        });
        Promise.all([work1,work2,work3]).then(res=>{
          console.log(res);
        })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 看着上面的代码,我一直在想,这为什么可以做到并发,我想想中的并发是这个请求同一时间发送,但是我搜来搜去,Promise.all 可以同时请求多个接口,这句话是错误的~我后面也调试发现并不是在同一时间发送ajax请求的,而是顺序发送,最后统一处理返回的结果

    • 我们知道,js是单线程的,所以分为同步和异步,我们创建promise的时候是同步执行的,nextTick才是异步执行的,所以Promise里面的函数是同步任务

    let work1 = new Promise((resolve,reject)=>{
        //同步任务
        resolve(axios.get('https://api.oick.cn/dutang/api.php'))
    });
    
    let work2 = new Promise((resolve,reject)=>{
        //同步任务
        resolve(axios.get('https://api.oick.cn/yiyan/api.php'))
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 所以在没有调用promise.all之前,ajax请求已经被发送了,只不过在promise.all的.then才统一接收处理

    可以看到,如果是统一时间发送的,我在调试的时候应该说Promise.all才执行ajax发送请求,但是我在经过let work2 的时候停顿一会后才执行let work3处的代码**,然后才准备执行**promise.all方法, 就会发现,前几天的数据请求状态为200了,也是在promise.all之前就发送了这个请求,而不是说执行promise.all这代码的时候才发送ajax请求

    • 等待了很久后,终止调试,发现正常输出返回的结果,而没有超时,所以就说明不是在promise.all才发送请求,而是我们在promise.all做最终处理
  • 相关阅读:
    Technical Support Website Statement
    【占坑】Redis key设计问题
    接口高可用
    自动驾驶感知算法实战11——多传感器融合感知方案详解
    季节性壁炉布置:让您的家温馨如冬季仙境
    YoloV5改进实战:使用MPDIoU改进YoloV5
    MECT4CNER 代码遇到的问题
    文件包含漏洞利用的几种方法
    单链表的简单使用
    山西电力市场日前价格预测【2023-09-25】
  • 原文地址:https://blog.csdn.net/u014582342/article/details/127942272