成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

盤點JavaScript中的Promise鏈的高級用法

開發 前端
有一系列的異步任務要一個接一個地執行 — 例如,加載腳本。如何寫出更好的代碼呢?Promise 提供了一些方案來做到這一點。

一、前言

有一系列的異步任務要一個接一個地執行 — 例如,加載腳本。如何寫出更好的代碼呢?

Promise 提供了一些方案來做到這一點。

二、案例分析

1.運行流程如下

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

//1. 初始 promise 在 1 秒后進行 resolve (*),


//2. 然后 .then 處理程序(handler)被調用 (**)。


//3. 它返回的值被傳入下一個 .then 處理程序(handler)(***)。

之所以這么運行,是因為對 promise.then 的調用會返回了一個 promise,所以可以在其之上調用下一個 .then。

當處理程序(handler)返回一個值時,它將成為該 promise 的 result,所以將使用它調用下一個 .then。

新手常犯的一個經典錯誤:從技術上講,也可以將多個 .then 添加到一個 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;
});

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

例1:fetch

在前端編程中,promise 通常被用于網絡請求。

案例:

將使用 [etch方法從遠程服務器加載用戶信息。它有很多可選的參數。

let promise = fetch(url);

執行這條語句,向 url 發出網絡請求并返回一個 promise。當遠程服務器返回 header(是在 全部響應加載完成前)時,該 promise 用使用一個 response 對象來進行 resolve。

為了讀取完整的響應,應該調用 response.text() 方法:當全部文字(full text)內容從遠程服務器下載完成后,它會返回一個 promise,該 promise 以剛剛下載完成的這個文本作為 result 進行 resolve。

下面這段代碼向 user.json 發送請求,并從服務器加載該文本:

fetch('/article/promise-chaining/user.json')
  // 當遠程服務器響應時,下面的 .then 開始執行
  .then(function(response) {
    // 當 user.json 加載完成時,response.text() 會返回一個新的 promise
    // 該 promise 以加載的 user.json 為 result 進行 resolve
    return response.text();
  })
  .then(function(text) {
    // ...這是遠程文件的內容
    alert(text); // {"name": "iliakan", "isAdmin": true}
  });

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

為了簡潔,還將使用箭頭函數:

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

現在,讓用加載好的用戶信息搞點事情。

例如,可以多發一個到 GitHub 的請求,加載用戶個人資料并顯示頭像:

// 發送一個對 user.json 的請求
fetch('/article/promise-chaining/user.json')
  // 將其加載為 JSON
  .then(response => response.json())
  // 發送一個到 GitHub 的請求
  .then(user => fetch(`https://api.github.com/users/${user.name}`))
  // 將響應加載為 JSON
  .then(response => response.json())
  // 顯示頭像圖片(githubUser.avatar_url)3 秒(也可以加上動畫效果)
  .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); // (*)
  });

這段代碼可以工作,具體細節請看注釋。但是,這兒有一個潛在的問題,一個新手使用 promise 的典型問題。

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

為了使鏈可擴展,需要返回一個在頭像顯示結束時進行 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 秒后觸發
  .then(githubUser => alert(`Finished showing ${githubUser.name}`));

圖片

注:

也就是說,第 (*) 行的 .then 處理程序(handler)現在返回一個 new Promise,只有在 setTimeout 中的 resolve(githubUser) (**) 被調用后才會變為 settled。鏈中的下一個 .then 將一直等待這一時刻的到來。

作為一個好的做法,異步行為應該始終返回一個 promise。這樣就可以使得之后計劃后續的行為成為可能。即使現在不打算對鏈進行擴展,但之后可能會需要。

三、總結

本文基于JavaScript基礎,介紹了Promise 鏈的高級用法,主要介紹了使用Promise時新手常會出現的幾個問題,對這幾個問題進行詳細的解答。

通過案例的分析,能夠更直觀的展示。采用JavaScript語言,能夠幫助你更好的學習JavaScript。

代碼很簡單。希望能夠幫助你更好的學習。

責任編輯:華軒 來源: 前端進階學習交流
相關推薦

2021-08-10 09:57:27

JavaScriptPromise 前端

2015-07-23 11:59:27

JavascriptPromise

2022-07-03 08:06:40

JavaScript語言代碼

2021-02-07 22:59:55

JavaScript編程方法鏈

2021-09-04 07:56:44

Pythonos模塊

2011-05-25 14:23:55

Javascriptthis

2021-10-09 07:10:30

JavaScriptBigIn函數

2021-10-09 07:10:31

JavaScript對象Python

2023-09-15 15:31:23

異步編程Promise

2009-06-17 15:01:07

javascript

2017-03-10 10:16:37

PythonRequests庫

2011-05-12 18:26:08

Javascript作用域

2022-04-04 09:12:18

Python內置函數

2021-06-07 09:44:10

JavaScript開發代碼

2022-10-11 23:50:43

JavaScript編程Promise

2021-06-15 10:01:27

JavaScript數組遍歷Entries

2021-08-31 10:01:04

JavaScript函數屬性

2021-09-03 10:00:00

JavaScript迭代對象

2021-09-14 07:26:25

JavaScript迭代對象

2024-11-14 13:15:22

JavaScript可迭代數組
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美中文字幕在线观看 | 免费能直接在线观看黄的视频 | 欧美bondage紧缚视频 | 久久亚洲一区二区三区四区 | 亚洲一区中文字幕在线观看 | 国产精品久久久久久久久久不蜜臀 | 亚洲国产成人精 | 国产精品美女久久久久aⅴ国产馆 | 欧美一区永久视频免费观看 | 国产精品乱码一二三区的特点 | 超碰电影 | www.国产日本 | 国产精品99久 | 日韩视频在线一区 | 成人三级在线观看 | 精品国产视频 | 精品国产鲁一鲁一区二区张丽 | 亚洲国产黄色av | 久久三区 | 青青操av | 久久精品一区二区 | 中文精品视频 | 欧美一级网站 | 日韩精品一区二区三区视频播放 | 欧美一区免费 | 欧美xxxx日本| 国产一级电影在线 | 欧美国产日韩在线 | 久久天堂| 亚洲二区视频 | 日韩欧美在线观看 | 久久久久久久电影 | 亚洲精品乱码久久久久久按摩 | 爱草视频 | 波多野结衣一区二区三区在线观看 | 欧美日韩精品一区二区天天拍 | 日批免费观看 | 国产一级久久久久 | 久久久久久国产 | 午夜av电影院| 最近最新中文字幕 |