一个关于AJAX并发的问题

题目

同时并发十个AJAX请求,若是捕获错误不超过三次就返回全部数据,超过三次返回错误,应该怎么设计?promise

思考

由于是并发,首先想到Promise.all,可是这个是捕获到错误就不朝下走了,咱们是否能够在捕获错误没超过三次的时候,强制朝下走呢?
若是不用Promise.all,咱们是否是能够本身写一个捕获三次错误才返回的变异版Promise.all?bash

方案一

咱们知道新的跨网络异步获取资源——fetch,这个API自己返回的就是Promise,很是方便后续处理,因此咱们在这采用这个新接口。
第一个考虑的方案是即便捕获到错误了,没超过三次,就强行走下去。这个“强行走下去”其实说白了就是不reject而是继续resolve网络

const _fetch = (function(){
    // 错误累计
    let errorCount = 0
    return (url,data = {}) => {
        return fetch.post(url,data).then( res => {
            // 成功以后,仍是要返回一个promise对象,由于Promise.all只接收Promise实例
            return Promise.resolve(res)
        }).catch( err => {
            // 捕获到错误的时候,由于使用闭包,因此错误数能够累加
            errorCount++
            // 若是没有超过3次,强行resolve,不中断Promise.all,超过直接返回错误中断
            if(errorCount===3) {
                Promise.reject(err)
            } else {
                Promise.resolve(err)
            }
        })
    }
}())

// 调用
Promise.all([
    _fetch('/a'),
    _fetch('/b'),
]).then(res => {
    console.log(res)
})
复制代码

方案二

promise.all内部是捕获一次就中断,咱们能够本身从新定义一个相似的方法,使之三次(或自定义次数)以后再中断闭包

const _promiseAll = function(list) {
    // promise.all最后返回的仍是一个Promise实例
    return new Promise((reslove, reject) => {
        let value = [] // 返回数据
        let count = 0 // 返回数据累计
        let errorCount = 0 // 错误累计
        for(let [i, p] of list.entries) {
            // 以防万一,实例化list项
            Promise.resolve(p).then(res => {
                value[i] = res
                count ++
                // 若是所有走完,返回数据
                if(count === list.length) resolve(values)
            }).catch(err => {
                errorCount ++ 
                // 若是错误累计没到3次,依然定义数据,超出三次直接返回错误
                if(errorCount <= 3) {
                    value[i] = err
                } else {
                  reject(err)  
                }
            })
        }
    })
}

// 调用
_promiseAll([
    fetch('/a'),
    fetch('/b'),
]).then(res => {
    console.log(res)
})
复制代码

以上是两种方案的思考,有待实际验证。并发

相关文章
相关标签/搜索