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

Promise

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

1. Promise特點(diǎn)

  • 承諾將來(lái)會(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)行中浪箭,表示還沒(méi)有得到結(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)過(guò)程的當(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 - 代表未初始化。 還沒(méi)有調(diào)用 open 方法
1 - 代表正在加載握玛。 open 方法已被調(diào)用够傍,但 send 方法還沒(méi)有被調(diào)用
2 - 代表已加載完畢。send 已被調(diào)用挠铲。請(qǐng)求已經(jīng)開(kāi)始
3 - 代表正在與服務(wù)器交互中冕屯。服務(wù)器正在解析響應(yīng)內(nèi)容
4 - 代表完成。響應(yīng)發(fā)送完畢

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

4. Promise 語(yǔ)法

代碼以實(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 重要語(yǔ)法

  • 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方法也是通過(guò)Promise進(jìn)行了封裝,最終返回的是一個(gè)Promise對(duì)象财边,因此這樣我們就可以將數(shù)據(jù)請(qǐng)求與數(shù)據(jù)處理放在不同的模塊肌括,即使用一個(gè)統(tǒng)一的模塊來(lái)管理所有的數(shù)據(jù)請(qǐng)求
    
        // 獲取當(dāng)天的信息
        getDayInfo = function() {
            return $.get(API.dayInfo);
        }
    
        // 獲取type信息
        getTypeInfo = function() {
            return $.get(API.typeInfo);
        };
    
        return {
            getDayInfo: getDayInfo,
            getTypeInfo: getTypeInfo
        }
    });
    

    可以增加過(guò)濾處理

    • 拿到數(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ù)分離開(kāi)來(lái)紧索,維護(hù)起來(lái)就更加方便了,代碼結(jié)構(gòu)也足夠清晰
    })
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菜谣,一起剝皮案震驚了整個(gè)濱河市珠漂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尾膊,老刑警劉巖媳危,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異冈敛,居然都是意外死亡待笑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)抓谴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)暮蹂,“玉大人,你說(shuō)我怎么就攤上這事癌压∽迪溃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵措拇,是天一觀(guān)的道長(zhǎng)我纪。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么浅悉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任趟据,我火速辦了婚禮,結(jié)果婚禮上术健,老公的妹妹穿的比我還像新娘汹碱。我一直安慰自己,他們只是感情好荞估,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布咳促。 她就那樣靜靜地躺著,像睡著了一般勘伺。 火紅的嫁衣襯著肌膚如雪跪腹。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天飞醉,我揣著相機(jī)與錄音冲茸,去河邊找鬼。 笑死缅帘,一個(gè)胖子當(dāng)著我的面吹牛轴术,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钦无,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼逗栽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了失暂?” 一聲冷哼從身側(cè)響起彼宠,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎趣席,沒(méi)想到半個(gè)月后兵志,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宣肚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年想罕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霉涨。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡按价,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笙瑟,到底是詐尸還是另有隱情楼镐,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布往枷,位于F島的核電站框产,受9級(jí)特大地震影響凄杯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秉宿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一戒突、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧描睦,春花似錦膊存、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至韵丑,卻和暖如春爵卒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背埂息。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工技潘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遥巴,地道東北人千康。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像铲掐,于是被迫代替她去往敵國(guó)和親拾弃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

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