• Promise.all 缺陷


    Promise.all 缺陷

    都知道 Promise.all 具有并发执行异步任务的能力。但它的最大问题就是如果其中某个任务出现异常(reject),所有任务都会挂掉,Promise 直接进入 reject 状态。

    想象这个场景:你的页面有三个区域,分别对应三个独立的接口数据,使用 Promise.all 来并发三个接口,如果其中任意一个接口服务异常,状态是 reject,这会导致页面中该三个区域数据全都无法渲染出来,因为任何 reject 都会进入 catch 回调, 很明显,这是无法接受的,如下:

    let a= new Promise((resolve,reject)=>{
      //异步操作...
      resolve({ code: 200,msg:"请求成功"})
    })
    let b= new Promise((resolve,reject)=>{
      //异步操作...
      resolve({ code: 200,msg:"请求成功"})
    })
    let c= new Promise((resolve,reject)=>{
      //异步操作...
      reject({ code: 500,msg:"服务器出现异常"})
    })
    //使用Promise.all 进行并发执行异步任务
    Promise.all([a,b,c])
    .then((res) => {
        // 只有 上面所有的请求都是 resolve (成功) 的时候才会进入此回调中
        console.log(res,"res")
    })
    .catch((error) => {
        // 上面的请求中,只要有一个是reject (失败) 就会进入此回调
        console.log(error,"error")
        // error: {code: 500, msg: "服务异常"}
    })
    

    Promise.allSettled

    当我们处理多个promise时,尤其是当它们相互依赖时,记录每个事件在调试中发生的错误可能很有用。使用Promise.allSettled,它会创建一个新的promise,在所有promise完成后返回一个包含每个promise结果的数组。
    let a= new Promise((resolve,reject)=>{
      //异步操作...
      resolve({ code: 200,msg:"请求成功"})
    })
    let b= new Promise((resolve,reject)=>{
      //异步操作...
      resolve({ code: 200,msg:"请求成功"})
    })
    let c= new Promise((resolve,reject)=>{
      //异步操作...
      reject({ code: 500,msg:"服务器出现异常"})
    })
    //使用进行并发请求
    Promise.allSettled([a,b,c]).then((data=>{
      console.log(data,"data")
    }))
    //结果
    [{"status":"fulfilled","value":{"code":200,"msg":"请求成功"}},{"status":"fulfilled","value":{"code":200,"msg":"请求成功"}},{"status":"rejected","reason":{"code":500,"msg":"服务器出现异常"}}] 
    

    Promise.allSettled 的优势

    Promise.allSettled跟``Promise.all类似 都是进行并发请求,但是,我们在上面的两个例子中,显然是已经看到了他们的一些区别,在使用Promise.all进行并发请求的时候,只要有一个请求出现问题(异常),所有的请求正常的也都不能拿到数据,但是在我们的业务的开发中,我们需要保障我们业务的最大的可访问性,就是在我们执行并发任务中,不管我这个并发任务中的一任何个任务是正常还是异常,我们都需要拿到返回的对应的状态,在ES11中Promise.allSettled就为我们解决了这个问题,它和Promise.all类似,参数接受一个Promise的数组,返回一个新的Promise,也就是说当Promise全部处理完成后,我们可以拿到每个Promise的状态, 而不管是否处理成功。我们可以在then里面通过filter来过滤出想要的业务逻辑结果,这样就解决了Promise.all` 的缺陷
  • 相关阅读:
    WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构
    WCF后续之旅(13): 创建一个简单的WCF SOAP Message拦截、转发工具[上篇]
    Enterprise Library深入解析与灵活应用(6):自己动手创建迷你版AOP框架
    [原创]WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿
    WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成
    WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘
    谈谈基于SQL Server 的Exception Handling
    Is this a MS EnterLib DAAB BUG or not?
    难道调用ThreadPool.QueueUserWorkItem()的时候,真是必须调用Thread.Sleep(N)吗?
    WCF中的Binding模型之一: Binding模型简介
  • 原文地址:https://www.cnblogs.com/wgy0528/p/13450877.html
Copyright © 2020-2023  润新知