利用Promise知識(shí),用原生JS封裝Ajax

Promise

Promise 就是一個(gè)對(duì)象,用來傳遞異步操作的消息。有了 Promise 對(duì)象,就可以將異步操作以同步操作的流程表達(dá)出來。

1. Promise特點(diǎn)

  • 承諾將來會(huì)執(zhí)行
  • 防止回調(diào)地獄 - Callback Hell
  • 可以進(jìn)行then的鏈?zhǔn)綀?zhí)行
  • 區(qū)分?jǐn)?shù)據(jù)請(qǐng)求和數(shù)據(jù)處理
  • 三種狀態(tài)
    • pending:等待中,或者進(jìn)行中,表示還沒有得到結(jié)果
    • resolved(fullfilled):已經(jīng)完成,表示得到了我們想要的結(jié)果,可以繼續(xù)往下執(zhí)行
    • rejected:也表示得到結(jié)果,但是由于結(jié)果并非我們所愿,因此拒絕執(zhí)行
  • 調(diào)用時(shí)會(huì)被傳遞兩個(gè)參數(shù):resolvereject函數(shù)
  • 具備then()方法,對(duì)于then()方法有以下簡(jiǎn)單的要求:
    1. 接收完成態(tài)、錯(cuò)誤態(tài)的回調(diào)方法
    2. 可選地支持progress事件回調(diào)作為第三個(gè)方法
    3. 只接受function對(duì)象
    4. 返回Promise對(duì)象,以實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

2. 如何創(chuàng)建AJAX

一個(gè)Ajax建立要了解以下幾點(diǎn):

  • XMLHttpRequest對(duì)象的工作流程
  • 兼容性處理
  • 事件的觸發(fā)條件
  • 事件的觸發(fā)順序

步驟:

  1. 創(chuàng)建XMLHttpRequest對(duì)象,也就是創(chuàng)建一個(gè)異步調(diào)用對(duì)象。
  2. 創(chuàng)建一個(gè)新的HTTP請(qǐng)求,并指定該HTTP請(qǐng)求的方法、URL及驗(yàn)證信息。
  3. 設(shè)置響應(yīng)HTTP請(qǐng)求狀態(tài)變化的函數(shù)。
  4. 發(fā)送HTTP請(qǐng)求。
  5. 獲取異步調(diào)用返回的數(shù)據(jù)。
  6. 使用JavaScript和DOM實(shí)現(xiàn)局部刷新。

3. 利用Promise知識(shí),用原生JS封裝AJAX

var url = '/請(qǐng)求的路徑';
var params = {
    id: 'id=123',
    limit: 'limit=10'
};

// 封裝一個(gè)get請(qǐng)求的方法
function getJSON(url) {
    return new Promise(function (resolve, reject) {
        var XHR = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');

        XHR.onreadystatechange = function () {
            //readyState屬性表示請(qǐng)求/響應(yīng)過程的當(dāng)前活動(dòng)階段。
            if (XHR.readyState == 4) {
                if ((XHR.status >= 200 && XHR.status < 300) || XHR.status == 304) {
                    try {
                        //獲取數(shù)據(jù)
                        var response = JSON.parse(XHR.responseText);
                        resolve(response);
                    } catch (e) {
                        reject(e);
                    }
                } else {
                    reject(new Error("Request was unsuccessful: " + XHR.statusText));
                }
            }
        }
        XHR.open('GET', url + '?' + params.join('&'), true);
        XHR.send(null);
    })
}

getJSON(url).then(resp => console.log(resp));

readyState
0 - 代表未初始化。 還沒有調(diào)用 open 方法
1 - 代表正在加載。 open 方法已被調(diào)用,但 send 方法還沒有被調(diào)用
2 - 代表已加載完畢。send 已被調(diào)用。請(qǐng)求已經(jīng)開始
3 - 代表正在與服務(wù)器交互中。服務(wù)器正在解析響應(yīng)內(nèi)容
4 - 代表完成。響應(yīng)發(fā)送完畢

readyState的值等于3,就是“流”(streaming),它是提升數(shù)據(jù)性能的強(qiáng)大工具。

4. Promise 語法

代碼以實(shí)現(xiàn)異步操作img為例

4.1 ES5 異步Callback實(shí)現(xiàn)

function loadImg(src, callback, fail) {
    var img = document.createElement('img')
    img.onload = function () {
        callback(img)
    }
    img.onerror = function () {
        fail()
    }
    img.src = src
}
var src = 'https://img.mukewang.com/5be2bcb30001a46709360316.jpg'
loadImg(src, function (img) {
    console.log(img.width)
}, function () {
    console.log('failed')
})

4.2 Promise實(shí)現(xiàn)

function loadImg(src) {
    const promise = new Promise(function (resolve, resolve) {
        var img = document.createElement('img')
        img.onload = function () {
            resolve(img)
        }
        img.onerror = function () {
            reject()
        }
        img.src = src
    })
    return promise
}


var src = 'https://img.mukewang.com/5be2bcb30001a46709360316.jpg'
var result = loadImg(src)

result.then(function (img) {
    console.log(img.width)
}, function () {
    console.log('failed')
})
result.then(function (img) {
    console.log(img.height)
})

優(yōu)點(diǎn):便于集成、擴(kuò)展
注意:

  • new Promise 實(shí)例,必須要 return
  • new Promise 時(shí)要傳入函數(shù),函數(shù)有 resolve reject 兩個(gè)參數(shù)
  • 成功時(shí)執(zhí)行 resolve() 失敗時(shí)執(zhí)行 reject()

4.3 重要語法

  • Promise.all接收一個(gè)Promise對(duì)象組成的數(shù)組作為參數(shù),當(dāng)這個(gè)數(shù)組所有的Promise對(duì)象狀態(tài)都變成resolved或者rejected的時(shí)候,它才會(huì)去調(diào)用then方法。

  • Promise.race與Promise.all相似的是,Promise.race都是以一個(gè)Promise對(duì)象組成的數(shù)組作為參數(shù),不同的是,只要當(dāng)數(shù)組中的其中一個(gè)Promsie狀態(tài)變成resolved或者rejected時(shí),就可以調(diào)用.then方法了。

  • 如何有效的將ajax的數(shù)據(jù)請(qǐng)求和數(shù)據(jù)處理分別放在不同的模塊中進(jìn)行管理

    • 將所有的數(shù)據(jù)請(qǐng)求這個(gè)動(dòng)作放在同一個(gè)模塊中統(tǒng)一管理
    define(function(require) {
        var API = require('API');
    
        // 因?yàn)閖Query中的get方法也是通過Promise進(jìn)行了封裝,最終返回的是一個(gè)Promise對(duì)象,因此這樣我們就可以將數(shù)據(jù)請(qǐng)求與數(shù)據(jù)處理放在不同的模塊,即使用一個(gè)統(tǒng)一的模塊來管理所有的數(shù)據(jù)請(qǐng)求
    
        // 獲取當(dāng)天的信息
        getDayInfo = function() {
            return $.get(API.dayInfo);
        }
    
        // 獲取type信息
        getTypeInfo = function() {
            return $.get(API.typeInfo);
        };
    
        return {
            getDayInfo: getDayInfo,
            getTypeInfo: getTypeInfo
        }
    });
    

    可以增加過濾處理

    • 拿到數(shù)據(jù)并處理數(shù)據(jù)
    // components/calendar.js
    define(function(require) {
        var request = require('request');
    
        // 拿到數(shù)據(jù)之后,需要處理的組件,可以根據(jù)數(shù)據(jù)渲染出需求想要的樣式
    
        request.getTypeInfo()
            .then(function(resp) {
    
                // 拿到數(shù)據(jù),并執(zhí)行處理操作
                console.log(resp);
            })
    
        // 這樣,我們就把請(qǐng)求數(shù)據(jù),與處理數(shù)據(jù)分離開來,維護(hù)起來就更加方便了,代碼結(jié)構(gòu)也足夠清晰
    })
    
最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Promise 對(duì)象 Promise 的含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,834評(píng)論 1 56
  • 一、Promise的含義 Promise在JavaScript語言中早有實(shí)現(xiàn),ES6將其寫進(jìn)了語言標(biāo)準(zhǔn),統(tǒng)一了用法...
    Alex灌湯貓閱讀 887評(píng)論 0 2
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 11,129評(píng)論 26 95
  • 前言 本文旨在簡(jiǎn)單講解一下javascript中的Promise對(duì)象的概念,特性與簡(jiǎn)單的使用方法。并在文末會(huì)附上一...
    _暮雨清秋_閱讀 2,313評(píng)論 0 3
  • 你不知道JS:異步 第三章:Promises 在第二章,我們指出了采用回調(diào)來表達(dá)異步和管理并發(fā)時(shí)的兩種主要不足:缺...
    purple_force閱讀 2,243評(píng)論 0 4

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