一個關於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)
})
複製代碼

以上是兩種方案的思考,有待實際驗證。併發

相關文章
相關標籤/搜索