<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          盤(pán)點(diǎn)JavaScript中的Promise 鏈的高級(jí)用法

          共 3848字,需瀏覽 8分鐘

           ·

          2021-08-11 23:38

          點(diǎn)擊上方“前端進(jìn)階學(xué)習(xí)交流”,進(jìn)行關(guān)注

          回復(fù)“前端”即可獲贈(zèng)前端相關(guān)學(xué)習(xí)資料

          濁酒不銷(xiāo)憂國(guó)淚,救時(shí)應(yīng)仗出群才。

          大家好,我進(jìn)階學(xué)習(xí)者。

          一、前言

          有一系列的異步任務(wù)要一個(gè)接一個(gè)地執(zhí)行 — 例如,加載腳本。如何寫(xiě)出更好的代碼呢?

          Promise 提供了一些方案來(lái)做到這一點(diǎn)。


          二、案例分析

          1.運(yùn)行流程如下

          它的理念是將 result 通過(guò) .then 處理程序(handler)鏈進(jìn)行傳遞。

          //1. 初始 promise 在 1 秒后進(jìn)行 resolve (*),
          //2. 然后 .then 處理程序(handler)被調(diào)用 (**)。
          //3. 它返回的值被傳入下一個(gè) .then 處理程序(handler)(***)。

          之所以這么運(yùn)行,是因?yàn)閷?duì) promise.then 的調(diào)用會(huì)返回了一個(gè) promise,所以可以在其之上調(diào)用下一個(gè) .then。

          當(dāng)處理程序(handler)返回一個(gè)值時(shí),它將成為該 promise 的 result,所以將使用它調(diào)用下一個(gè) .then。

          新手常犯的一個(gè)經(jīng)典錯(cuò)誤:從技術(shù)上講,也可以將多個(gè) .then 添加到一個(gè) promise 上。但這并不是 promise 鏈(chaining)。

          例 :

          let promise = new Promise(function(resolve, reject) {  setTimeout(() => resolve(1), 1000);});promise.then(function(result) {  alert(result); // 1  return result * 2;});promise.then(function(result) {  alert(result); // 1  return result * 2;});promise.then(function(result) {  alert(result); // 1  return result * 2;});

          f98092a031b96b924161df4f96655b37.webp

          在這里所做的只是一個(gè) promise 的幾個(gè)處理程序(handler)。他們不會(huì)相互傳遞 result;相反,它們之間彼此獨(dú)立運(yùn)行處理任務(wù)。

          例1:fetch

          在前端編程中,promise 通常被用于網(wǎng)絡(luò)請(qǐng)求。

          案例:

          將使用 [etch方法從遠(yuǎn)程服務(wù)器加載用戶(hù)信息。它有很多可選的參數(shù)。

          let promise = fetch(url);

          執(zhí)行這條語(yǔ)句,向 url 發(fā)出網(wǎng)絡(luò)請(qǐng)求并返回一個(gè) promise。當(dāng)遠(yuǎn)程服務(wù)器返回 header(是在 全部響應(yīng)加載完成前)時(shí),該 promise 用使用一個(gè) response 對(duì)象來(lái)進(jìn)行 resolve。

          為了讀取完整的響應(yīng),應(yīng)該調(diào)用 response.text() 方法:當(dāng)全部文字(full text)內(nèi)容從遠(yuǎn)程服務(wù)器下載完成后,它會(huì)返回一個(gè) promise,該 promise 以剛剛下載完成的這個(gè)文本作為 result 進(jìn)行 resolve。

          下面這段代碼向 user.json 發(fā)送請(qǐng)求,并從服務(wù)器加載該文本:

          fetch('/article/promise-chaining/user.json')  // 當(dāng)遠(yuǎn)程服務(wù)器響應(yīng)時(shí),下面的 .then 開(kāi)始執(zhí)行  .then(function(response) {    // 當(dāng) user.json 加載完成時(shí),response.text() 會(huì)返回一個(gè)新的 promise    // 該 promise 以加載的 user.json 為 result 進(jìn)行 resolve    return response.text();  })  .then(function(text) {    // ...這是遠(yuǎn)程文件的內(nèi)容    alert(text); // {"name": "iliakan", "isAdmin": true}  });

          05e6a3afa29f0254a29bb92f1999c3af.webp

          從 fetch 返回的 response 對(duì)象還包括 response.json() 方法,該方法讀取遠(yuǎn)程數(shù)據(jù)并將其解析為 JSON。在的例子中,這更加方便,所以讓切換到這個(gè)方法。

          為了簡(jiǎn)潔,還將使用箭頭函數(shù):

          // 同上,但是使用 response.json() 將遠(yuǎn)程內(nèi)容解析為 JSONfetch('/article/promise-chaining/user.json')  .then(response => response.json())  .then(user => alert(user.name)); // iliakan, got user name

          現(xiàn)在,讓用加載好的用戶(hù)信息搞點(diǎn)事情。

          例如,可以多發(fā)一個(gè)到 GitHub 的請(qǐng)求,加載用戶(hù)個(gè)人資料并顯示頭像:

          // 發(fā)送一個(gè)對(duì) user.json 的請(qǐng)求fetch('/article/promise-chaining/user.json')  // 將其加載為 JSON  .then(response => response.json())  // 發(fā)送一個(gè)到 GitHub 的請(qǐng)求  .then(user => fetch(`https://api.github.com/users/${user.name}`))  // 將響應(yīng)加載為 JSON  .then(response => response.json())  // 顯示頭像圖片(githubUser.avatar_url)3 秒(也可以加上動(dòng)畫(huà)效果)  .then(githubUser => {    let img = document.createElement('img');    img.src = githubUser.avatar_url;    img.className = "promise-avatar-example";    document.body.append(img);    setTimeout(() => img.remove(), 3000); // (*)  });

          b2d1c2875f97301eb8531fd874833a3b.webp

          這段代碼可以工作,具體細(xì)節(jié)請(qǐng)看注釋。但是,這兒有一個(gè)潛在的問(wèn)題,一個(gè)新手使用 promise 的典型問(wèn)題。

          請(qǐng)看 (*) 行:如何能在頭像顯示結(jié)束并被移除 之后 做點(diǎn)什么?例如,想顯示一個(gè)用于編輯該用戶(hù)或者其他內(nèi)容的表單。就目前而言,是做不到的。

          為了使鏈可擴(kuò)展,需要返回一個(gè)在頭像顯示結(jié)束時(shí)進(jìn)行 resolve 的 promise。

          就像這樣:

          fetch('/article/promise-chaining/user.json')  .then(response => response.json())  .then(user => fetch(`https://api.github.com/users/${user.name}`))  .then(response => response.json())  .then(githubUser => new Promise(function(resolve, reject) { // (*)    let img = document.createElement('img');    img.src = githubUser.avatar_url;    img.className = "promise-avatar-example";    document.body.append(img);    setTimeout(() => {      img.remove();      resolve(githubUser); // (**)    }, 3000);  }))  // 3 秒后觸發(fā)  .then(githubUser => alert(`Finished showing ${githubUser.name}`));

          bfe802aaae13eefd1ff1b8935259cac3.webp

          注:

          也就是說(shuō),第 (*) 行的 .then 處理程序(handler)現(xiàn)在返回一個(gè) new Promise,只有在 setTimeout 中的 resolve(githubUser) (**) 被調(diào)用后才會(huì)變?yōu)?settled。鏈中的下一個(gè) .then 將一直等待這一時(shí)刻的到來(lái)。

          作為一個(gè)好的做法,異步行為應(yīng)該始終返回一個(gè) promise。這樣就可以使得之后計(jì)劃后續(xù)的行為成為可能。即使現(xiàn)在不打算對(duì)鏈進(jìn)行擴(kuò)展,但之后可能會(huì)需要。


          三、總結(jié)

          本文基于JavaScript基礎(chǔ),介紹了Promise 鏈的高級(jí)用法,主要介紹了使用Promise時(shí)新手常會(huì)出現(xiàn)的幾個(gè)問(wèn)題,對(duì)這幾個(gè)問(wèn)題進(jìn)行詳細(xì)的解答。

          通過(guò)案例的分析,能夠更直觀的展示。采用JavaScript語(yǔ)言,能夠幫助你更好的學(xué)習(xí)JavaScript。

          代碼很簡(jiǎn)單。希望能夠幫助你更好的學(xué)習(xí)。

          -------------------?End?-------------------

          往期精彩文章推薦:

          73d62ad80fdd362f750997c40993c8a8.webp

          歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入前端學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群

          萬(wàn)水千山總是情,點(diǎn)個(gè)【在看】行不行

          瀏覽 39
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黑人借宿与人妻羽月希 | 欧美日韩一级在线观看 | 亚洲字幕在线观看 | 黄片免费观看网站 | 大香蕉伊人97 |