手動(dòng)promise封裝ajax

首先,定義傳入 ajax函數(shù)的默認(rèn)參數(shù)

var ajaxOptions = {
   url: '#',                       url地址,默認(rèn)"#"
   method:  'GET',                 請(qǐng)求方法,僅支持GET,POST,默認(rèn)GET
   async: true,                    是否異步,默認(rèn)true
   timeout: 0                      請(qǐng)求時(shí)限,超時(shí)將在promise中調(diào)用reject函數(shù)
   data: null,                     發(fā)送的數(shù)據(jù),該函數(shù)不支持處理數(shù)據(jù),將會(huì)直接發(fā)送
   dataType: 'text',               接受的數(shù)據(jù)的類(lèi)型,默認(rèn)為text
   headers: {}                     一個(gè)對(duì)象,包含請(qǐng)求頭信息
   onprogress: function (){},      處理onprogress的函數(shù)
   ouploadprogress: function() {}, 處理.upload.onprogress的函數(shù)
   xhr: null                       允許在函數(shù)外部創(chuàng)建xhr對(duì)象傳入,但必須不能是使用過(guò)的
}
/**
 * ajax函數(shù),返回一個(gè)promise對(duì)象
 * @return {Promise} 
 *   該函數(shù)注冊(cè)xhr.onloadend回調(diào)函數(shù),判斷xhr.status是否屬于 [200,300)&&304 ,
 *   如果屬于則promise引發(fā)resolve狀態(tài),允許拿到xhr對(duì)象
 *   如果不屬于,或已經(jīng)引發(fā)了ontimeout,onabort,則引發(fā)reject狀態(tài),也允許拿到xhr對(duì)象
 */
function ajax(optionsOverride) {
    // 將傳入的參數(shù)與默認(rèn)設(shè)置合并
    var options = {};
    for (var k in ajaxOptions) {
        options[k] = optionsOverride[k] || ajaxOptions[k];
    }
    options.async = options.async === false ? false : true;
    var xhr = options.xhr = options.xhr || new XMLHttpRequest();

    return new Promise(function (resolve, reject) {
        xhr.open(options.method, options.url, options.async);
        xhr.timeout = options.timeout;

        //設(shè)置請(qǐng)求頭
        for (var k in options.headers) {
            xhr.setRuquestHeader(k, options.headers[k]);
        }

        // 注冊(cè)xhr對(duì)象事件
        xhr.onprogress = options.onprogress;
        xhr.upload.onprogress = options.onuploadprogress;
        xhr.responseType = options.dataType;

        xhr.onabort = function () {
            reject(new Error({
                errorType: 'abort_error',
                xhr: xhr
            }));
        }
        xhr.ontimeout = function () {
            reject({
                errorType: 'timeout_error',
                xhr: xhr
            });
        }
        xhr.onerror = function () {
            reject({
                errorType: 'onerror',
                xhr: xhr
            })
        }
        xhr.onloadend = function () {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)
                resolve(xhr);
            else
                reject({
                    errorType: 'status_error',
                    xhr: xhr
                })
        }

        try {
            xhr.send(options.data);
        }
        catch (e) {
            reject({
                errorType: 'send_error',
                error: e
            });
        }
    })
}

使用方式如下:

ajax({
    url: 'http://localhost:8080/dy',
    async: true,
    onprogress: function (e) {
        console.log(e.position/e.total);
    },
    dataType:'text/json'
})
.then(function (xhr) { console.log(xhr.response.name); },
function (e) { console.log('失敗回調(diào)') })
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容