promise-基礎(chǔ)-ajax封裝

1.前言

總結(jié)前后端交互的幾種方式的時(shí)候,突然想起來之前小程序用promise封裝ajax,簡要記錄如下
這幾天閑來無事又梳理了下 promise


2.常規(guī)封裝

function getApi(url, data, successCB) {
  wx.showLoading({
    title: '加載中',
  })
  wx.request({
    url: baseUrl + url,
    data,
    header: {
      'content-type': 'application/json' // 默認(rèn)值
    },
    success: (res) => {
      if (res.code = 200) {
        //   回調(diào)到組件 ,數(shù)據(jù)給他
        successCB && successCB(res.data)
      } else {
        wx.showToast({
          title: '服務(wù)器錯(cuò)誤',
          icon: 'error',
          duration: 2000
        })
      }
    },
    fail: (err) => {
      wx.showToast({
        title: '服務(wù)器錯(cuò)誤',
        icon: 'error',
        duration: 2000
      })
      console.log("錯(cuò)誤信息:", err);
    },
    complete(res) {
      // console.log("complete",res);
      wx.hideLoading()
      // wx.stopPullDownRefresh()
    }
  })
}

3.promise封裝

const getApi = (url, data) => {
  wx.showLoading({
    title: '加載中',
    mask: true
  })
  // Promise 承諾:處理異步回調(diào) 同意  拒絕
  return new Promise(function (resolve, reject) {
    // 只能走一個(gè) 要么同意 要么拒絕
    // resolve() 回調(diào)then()
    // reject() 回調(diào)catch() 
    wx.request({
      url: baseUrl + url,
      data,
      header: {
        'content-type': 'application/json' // 默認(rèn)值
      },
      success: (res) => {
        resolve(res.data)
      },
      fail: () => {
        wx.showToast({
          title: '服務(wù)器錯(cuò)誤',
          icon: 'error',
          duration: 2000
        })
        reject("服務(wù)器錯(cuò)誤,請稍后重試");
      },
      complete(res) {
        // console.log("complete",res);
        wx.hideLoading()
        // wx.stopPullDownRefresh()
      }
    })
  })
}

4. 調(diào)用

var api = require('../../utils/api');
var shopUrl = ""
var data = {}
api.getApi(shopUrl,data).then(()=>{
 //處理數(shù)據(jù)
}).catch(()=>{
//異常處理
 wx.showToast({
        title: '服務(wù)器錯(cuò)誤',
        icon: 'error',
        duration: 2000
      })
})

5. why 為什么需要 promise

誕生背景,解決了哪些問題

  1. js中代碼都是單線程 異步執(zhí)行的.實(shí)現(xiàn)異步的方式主要是 回調(diào)函數(shù)

2.Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案更合理和更強(qiáng)大破婆。它由社區(qū)最早提出和實(shí)現(xiàn)涮坐,ES6 將其寫進(jìn)了語言標(biāo)準(zhǔn)辽俗,統(tǒng)一了用法,原生提供了Promise對象


6. 基礎(chǔ)概念

簡單說就是一個(gè)容器游昼,里面保存著某個(gè)未來才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果凿掂。

從語法上說灯荧,Promise 是一個(gè)對象,從它可以獲取異步操作的消息陕截。Promise提供統(tǒng)一的 API驳棱,各種異步操作都可以用同樣的方法進(jìn)行處

可以理解為 君子一諾千金,答應(yīng)的事情,等我這邊忙完,一定會(huì)給你個(gè)答復(fù),不管拒絕還是同意.


7. 核心要點(diǎn)

1.對象的狀態(tài)不受外界影響。

Promise對象代表一個(gè)異步操作农曲,有三種狀態(tài):pending(進(jìn)行中)社搅、fulfilled(已成功)rejected(已失敗)乳规。只有異步操作的結(jié)果形葬,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個(gè)狀態(tài)暮的。這也是Promise這個(gè)名字的由來

它的英語意思就是“承諾”笙以,表示其他手段無法改變。

2. 一旦狀態(tài)改變冻辩,就不會(huì)再變猖腕,任何時(shí)候都可以得到這個(gè)結(jié)果。

Promise對象的狀態(tài)改變恨闪,只有兩種可能:
pending變?yōu)?code>fulfilled和
pending變?yōu)?code>rejected倘感。

只要這兩種情況發(fā)生,狀態(tài)就凝固了咙咽,不會(huì)再變了老玛,會(huì)一直保持這個(gè)結(jié)果,這時(shí)就稱為resolved(已定型)钧敞。如果改變已經(jīng)發(fā)生了蜡豹,你再對Promise對象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果犁享。

這與事件(Event)完全不同余素,事件的特點(diǎn)是,如果你錯(cuò)過了它炊昆,再去監(jiān)聽桨吊,是得不到結(jié)果的


8. 缺點(diǎn)

1.無法取消Promise,一旦新建它就會(huì)立即執(zhí)行威根,無法中途取消。
2.如果不設(shè)置回調(diào)函數(shù)视乐,Promise內(nèi)部拋出的錯(cuò)誤洛搀,不會(huì)反應(yīng)到外部。
3.當(dāng)處于pending狀態(tài)時(shí)佑淀,無法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)


9. 案例

隨機(jī)數(shù)大于4 你贏了 武林盟主
比多久不清楚,所有用定期模擬,間隔時(shí)間也是變量

   var test = (resolve, reject) => {
            var randomNum = Math.random() * 10
            console.log("隨機(jī)是:", randomNum);
            // 比武什么時(shí)候結(jié)束 是不確定 ,用定時(shí)器模擬這個(gè)不確定
            setTimeout(() => {
                if (randomNum > 4) {
                    resolve("周潤發(fā) 賭王 贏了")
                } else {
                    reject("周潤發(fā) 問鼎賭王 失敗")
                }
            }, 1000 * randomNum)
        }

外界并不關(guān)心你們這場 比武的過程,只關(guān)注結(jié)果


10. then 你贏的結(jié)果

函數(shù)執(zhí)行成功 告訴Promise對象:執(zhí)行then
then方法返回的是一個(gè)新的Promise實(shí)例(注意留美,不是原來那個(gè)Promise實(shí)例)。
因此可以采用鏈?zhǔn)綄懛ㄉ烊校?code>then方法后面再調(diào)用另一個(gè)then方法谎砾。

  var p1 = new Promise(test)
 var p2 = p1.then(res => {
            console.log("成功:", res);
        })

Promise實(shí)例具有then方法,也就是說捧颅,then方法是定義在原型對象Promise.prototype上的景图。

它的作用是為Promise實(shí)例添加狀態(tài)改變時(shí)的回調(diào)函數(shù)。前面說過碉哑,then方法的第一個(gè)參數(shù)是resolved狀態(tài)的回調(diào)函數(shù)挚币,第二個(gè)參數(shù)是rejected狀態(tài)的回調(diào)函數(shù),它們都是可選的扣典。


11. catch 你輸?shù)慕Y(jié)果

函數(shù)執(zhí)行失敗時(shí)妆毕,我們告訴Promise對象: 執(zhí)行 catch方法

    var p3 = p2.catch(err=>{
        console.log("失敗:",err)
    })

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)


12. finally 不管輸贏 都會(huì)走

finally()方法用于指定不管Promise對象最后狀態(tài)如何贮尖,都會(huì)執(zhí)行的操作笛粘。該方法是 ES2018 引入標(biāo)準(zhǔn)的。

 var p4 = p3.finally(()=>{
   console.log("都會(huì)執(zhí)行")
})

13. 鏈?zhǔn)綄懛?/h1>
  new Promise((resolve, reject) => {
            var randomNum = Math.random() * 10
            console.log("隨機(jī)是:", randomNum);
            // 比武什么時(shí)候結(jié)束 是不確定 ,用定時(shí)器模擬這個(gè)不確定
            setTimeout(() => {
                if (randomNum > 4) {
                    resolve("周潤發(fā) 賭王 贏了")
                } else {
                    reject("周潤發(fā) 問鼎賭王 失敗")
                }
            }, 1000 * randomNum)
        }).then(res=>{
            console.log("成功:",res);
        }).catch(err=>{
            console.log("失敗:",err);
        })

14.原生ajax封裝

這里只是簡單的例子 ,具體的 請求參數(shù) 還需要另做

 <button onclick="sendBtn()">發(fā)送</button>
    <script>
        function sendBtn() {
            ajax("GET", "./data.json").then(res => {
                console.log("res:", res)
            }).catch(err => console.log(err))
        }
        // ajax函數(shù)將返回Promise對象:
        function ajax(method, url, data) {
            var request = new XMLHttpRequest();
            return new Promise(function (resolve, reject) {
                request.onreadystatechange = function () {
                    if (request.readyState === 4) {
                        if (request.status === 200) {
                         resolve(JSON.parse(request.responseText))
                        } else {
                            reject(request.status);
                        }
                    }
                };
                request.open(method, url);
                request.send(data);
            });
        }
    </script>

15. 總結(jié)

Promise最大的好處是:

1.在異步執(zhí)行的流程中远舅, 把執(zhí)行代碼和處理結(jié)果的代碼清晰地分離了

  1. 將異步操作以同步操作的流程表達(dá)出來闰蛔,避免了層層嵌套的回調(diào)函數(shù)

3.Promise對象提供統(tǒng)一的接口,使得控制異步操作更加容易


參考資料

promise基礎(chǔ)
阮一峰-promise
前端請求的5種方式


初心

我所有的文章都只是基于入門图柏,初步的了解序六;是自己的知識(shí)體系梳理;
如果能幫助到有緣人,非常的榮幸,一切都是為了部落的崛起
共勉
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蚤吹,隨后出現(xiàn)的幾起案子例诀,更是在濱河造成了極大的恐慌,老刑警劉巖裁着,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件繁涂,死亡現(xiàn)場離奇詭異,居然都是意外死亡二驰,警方通過查閱死者的電腦和手機(jī)扔罪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桶雀,“玉大人矿酵,你說我怎么就攤上這事唬复。” “怎么了全肮?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵敞咧,是天一觀的道長。 經(jīng)常有香客問我辜腺,道長休建,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任评疗,我火速辦了婚禮测砂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘百匆。我一直安慰自己邑彪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布胧华。 她就那樣靜靜地躺著,像睡著了一般宙彪。 火紅的嫁衣襯著肌膚如雪矩动。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天释漆,我揣著相機(jī)與錄音悲没,去河邊找鬼。 笑死男图,一個(gè)胖子當(dāng)著我的面吹牛示姿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逊笆,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼栈戳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了难裆?” 一聲冷哼從身側(cè)響起子檀,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乃戈,沒想到半個(gè)月后褂痰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡症虑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年缩歪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谍憔。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匪蝙,死狀恐怖主籍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情骗污,我是刑警寧澤崇猫,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站需忿,受9級特大地震影響诅炉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屋厘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一涕烧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汗洒,春花似錦议纯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至世杀,卻和暖如春阀参,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瞻坝。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工蛛壳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人所刀。 一個(gè)月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓衙荐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浮创。 傳聞我的和親對象是個(gè)殘疾皇子忧吟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

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