JavaScript >> Javascript 文檔 >  >> JavaScript

如何使用 Promise.all() 等待多個 Promise

在執行更多代碼之前,如何使用 Promise.all() 等待 Promise 調用數組解析。

在本教程中,我們將使用 CheatCode 的全棧 JavaScript 框架 Joystick。 Joystick 將前端 UI 框架與用於構建應用的 Node.js 後端結合在一起。

首先,我們要通過 NPM 安裝 Joystick。確保在安裝之前使用 Node.js 16+ 以確保兼容性(如果您需要學習如何安裝 Node.js 或在計算機上運行多個版本,請先閱讀本教程):

終端

npm i -g @joystick.js/cli

這將在您的計算機上全局安裝操縱桿。安裝好之後,接下來我們新建一個項目:

終端

joystick create app

幾秒鐘後,您將看到一條消息已註銷到 cd 進入你的新項目並運行 joystick start

終端

cd app && joystick start

在此之後,您的應用應該可以運行了,我們可以開始了。

編寫測試 Promise

雖然從技術上講,我們可以使用任何 JavaScript Promise 進行測試,但為了簡單起見,我們將從連接一個非常簡單的 Promise 開始:一個將超時設置為 timeoutInSeconds 的函數 並解析 setTimeout() 中函數返回的 Promise 超時完成後。

/lib/wait.js

export default (timeoutInSeconds = 0) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`Completed after ${timeoutInSeconds} seconds!`);
    }, timeoutInSeconds * 1000);
  });
};

這裡,在 /lib 裡面 當我們運行 joystick create app 時為我們創建的文件夾 上面,我們新建一個文件wait.js 並在其中添加一個 export default 接受 timeoutInSeconds 的函數 作為其唯一的參數(= 0 參數名稱後面的部分是我們設置默認值 0 如果沒有傳遞任何值)。

在該函數內部,我們返回一個 new Promise() .到那個new Promise() 例如,我們傳遞一個回調函數來定義 Promise 的行為。就像我們上面暗示的那樣,我們想要運行一個 setTimeout() , 使用 timeoutInSeconds 作為 setTimeout() 的延遲傳遞給我們 .

setTimeout() 的回調內部 ,在 timeoutInSeconds 之後 已經完成,我們調用resolve 當我們調用 new Promise() 時傳遞給我們的函數 .向它傳遞一個字符串,確認我們完成了請求的“等待”,以便在通過 Promise.all() 調用 Promise 時獲得返回值 .

這就是我們的測試 Promise。同樣,您可以使用任何返回 Promise 的函數進行下一步(例如,調用 fetch() 或一些返回 Promise 的第三方庫函數)。

使用 Promise.all()

現在,看看Promise.all()如何 工作,我們將使用 @joystick.js/ui 在我們的應用程序中創建一個簡單的組件 包內置到我們用於本教程的框架中。為簡單起見,我們將在 /ui/pages/index/index.js 處打開文件 它是在我們運行 joystick create app 時為我們創建的 早些時候。首先,我們將使用以下模板替換此文件的內容:

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  render: ({ state }) => {
    return `
      <div></div>
    `;
  },
});

export default Index;

這將為我們提供一個空白的 slate 組件來測試我們的 Promise.all() 來電。接下來,讓我們修改這個組件以添加我們的測試代碼(拉入我們的 /lib/wait.js 文件頂部的函數)並了解它是如何工作的。

/ui/pages/index/index.js

import ui from '@joystick.js/ui';
import wait from '../../../lib/wait';

const Index = ui.component({
  state: {
    running: false,
  },
  events: {
    'click button': (_event, component) => {
      component.setState({ running: true }, async () => {
        const results = await Promise.all([
          wait(1),
          wait(2),
          wait(4),
          wait(8),
        ]);
  
        console.log(results);
        component.setState({ running: false });
      });
    },
  },
  render: ({ state }) => {
    return `
      <div>
        <button ${state?.running ? 'disabled' : ''}>${!state?.running ? 'Start the Promise chain' : 'Running...'}</button>
      </div>
    `;
  },
});

export default Index;

render() 開始 ,我們添加了一個 <button></button> 我們可以點擊啟動我們的 Promise 鏈。為了確定它是否被禁用(以及它當前標籤讀取的內容),我們“拔掉”組件的當前 state 通過解構傳遞給 render() 的組件實例對象的值 .

如果 running 值為 true,我們要將按鈕標記為 disabled 所以它不可點擊並將其標籤更改為“正在運行...”如果我們查看對 ui.component() 的調用頂部附近 ,我們在傳遞給這個函數的選項對像上設置的第一個屬性(我們組件的定義)是一個對象 state 並在屬性 running 內 設置為 false .這是我們設置默認的 state 組件在瀏覽器中加載時的值(即按鈕 不會 頁面加載時禁用)。

接下來,在 events 中 在 state 下定義的對象 ,我們為 click 添加一個事件監聽器 我們的 <button></button> 上的事件 使用 click button .對於該屬性,我們傳遞一個函數以在 click 時調用 在按鈕上檢測到。在裡面,使用 component 實例作為第二個參數傳遞給事件處理程序(在我們可以忽略的 DOM 事件對象本身之後),我們調用組件的 .setState() 設置running的方法 到 true .

之後,我們傳遞一個回調函數(注意 async 的前綴 此函數上的關鍵字)在 setState() 之後調用 通話已完成。在裡面,我們創建了一個變量const results 它被分配了對 await Promise.all() 的調用 .到 Promise.all() ,我們將一系列調用傳遞給我們的 wait() 我們在文件頂部導入的函數。

記住:我們的 wait() 函數接收一個表示 timeoutInSeconds 的整數 我們希望我們的函數在解析之前等待。因為我們這裡的目標是演示對 Promise.all() 的調用 ,我們要調用 wait() 多次不同的超時。這將展示我們在完成某些任務之前需要等待的其他基於 Promise 的函數的實際延遲。在這裡,我們期望 Promise.all() 調用直到全部才解決 傳遞給它的 Promise 解決。

換句話說,我們希望單擊按鈕並延遲八 (8) 秒,直到 Promise.all() 解析,並將其結果存儲在 results 多變的。這裡的想法是,即使我們有一個 console.log() results 以及對 component.setState() 的另一個調用 啟用我們的 <button></button> 同樣,我們不希望在 Promise.all() 之前調用它們 8 秒後解決。

如果我們在瀏覽器中加載它並單擊我們的按鈕,我們應該會看到這個確切的結果,使用 results 包含一個字符串數組,每個字符串代表傳遞給 resolve() 的返回值 在我們的 wait() 內部 功能。

總結

在本教程中,我們學習瞭如何使用 Promise.all() 等待一系列 Promise。我們學習瞭如何定義一個等待一些 timeoutInSeconds 的簡單 JavaScript Promise 在解析之前完成,然後在操縱桿組件內部,如何連接事件偵聽器以調用 Promise.all() — 傳遞多個 wait() 對它有不同超時的調用——等待它解決並給我們返回 results 每次通話。


Tutorial JavaScript 教程
  1. 有興趣學習 React?這些會有所幫助

  2. IE10 發送帶小數(浮點值)的圖像按鈕單擊坐標導致 ParseInt32 FormatException

  3. Angular 中的 HttpContext 到底是什麼?

  4. ⚡ 使用 Preact (1 LOC) 讓 Gatsby 更快

  5. Node中打字稿的簡單模板

  6. 如何升級為軟件工程師 | AWS 社區建設者計劃

  7. 10 個值得一試的 jQuery 插件

  1. 在 Vue.js 組件中使用 Chrome 擴展 API

  2. 如何更新 react.js 中的“prevState”? [關閉]

  3. 🚀如何學習 JavaScript!困難的方式是可能的並且(容易!)。

  4. 在 Vue 3 中創建選項卡組件

  5. 使用 Github Actions 像專業人士一樣部署到 Github 頁面

  6. 如何開始使用帶有 Typescript 的 React

  7. 克隆並更改內部按鈕的onclick代碼

  1. 在 Airtable 上構建 AWS Lambda 函數的完整教程

  2. 使用此 WebDev 播客列表 🤘🚀🤘,在洗手的同時提高您的工作效率

  3. 口袋裡應該有的免費 React 資源。

  4. Angular 7 的新功能