在 JavaScript 中,promise 是一個正在進行操作的值的占位符。
你通常使用一個 promise 來管理你必須等待操作結果的情況。例如,將文件上傳到服務器並等待 API 調用的響應,或者只是要求用戶從他們的計算機中選擇一個文件。
在這篇文章中,你將通過建立一個像下面這樣的真實世界的例子應用來學習 JavaScript 的 promise。
Promise 是什麼promise 是一個簡單的函數,它返回一個你可以回調的 Object(對象)。
promise 對象上的回調只有在操作完成時才會被調用。在之前,回調將不得不等待,直到操作被fulfilled 或 rejected:
fetch(`some_api_url`).then((response)=>{//這裡的將等待獲取操作的完成});在一個 promise 最終確定之前( promise 要麼實現(fulfills),要麼被拒絕(rejected)),它必須經歷不同的狀態:
當一個 promise 被創建時,初始狀態是待定(pending)。然後根據操作的輸出,promise 要麼被 fulfilled,要麼被 rejected。
從上面的表格中,你可以很容易地看到根據 Promise 的每個狀態而被調用的回調:
fetch(`some_api_url`).then((response)=>{//當promisefulfilled 時,這將被調用}).catch((error)=>{//當promiserejected 時,這將被調用}).finally(()=>{//這將在最後面調用})如何在 JavaScript 中使用 Promises現在你已經了解了什麼是 promise,讓我們通過建立我們之前看到的電影搜索應用來演示如何在 JavaScript 中使用 promise。
一個基本的電影搜索應用程序應該有一個輸入字段,用戶可以在那裡搜索他們喜歡的電影。它還應該有一個用戶界面來顯示他們所搜索的電影的一些基本信息。
讓我們從創建 HTML 開始。
如何編寫 HTML為了本教程的目的和提供實際的例子,我將使用 Codepen,但你可以使用你喜歡的代碼編輯器。
創建一個index.html文件並添加以下代碼:
<divclass="wrapper"><headerclass="header"><divclass="header_logo">Movie</div><divclass="header_actions"><formonsubmit="handle_form(event)"id="header_form"><divclass="header_form-icon"><inputtype="search"class="header_form-input"placeholder="Search,PressEntertoSubmit"/><svgclass="icon"width="22px"height="22px"><usehref="#icon-search"/></svg></div></form><imgid="img_icon"width="32px"height="32px"src=""alt=""></div></header><mainid="main"><section><articleclass="movie"><divclass="movie_img"><imgid="img_src"src=""alt=""srcset=""></div><divclass="movie_info"><header><h1class="movie_title"></h1></header><divclass="movie_desc"></div><divclass="movie_details"><h2>Details</h2><ulclass="flex"><li>Premiered:<spanid="movie_date"></span></li><li>Rating:<spanid="movie_rating"></span></li><li>Runtime:<spanid="movie_runtime"></span></li><li>Status:<spanid="movie_status"></span></li></ul></div><ahref=""class="btn"target="_blank"rel="noopenernoreferrer"><svgclass="icon"width="16px"height="16px"><usehref="#icon-play"/></svg>WatchMovie</a></div></article><divclass="episodes_list"><h3class="episodes_title"></h3><olclass="episodes"id="episodes"></ol></div></section></main></div>上面我們只是創建了我們的電影應用程序的基礎。所以現在讓我們用一些 CSS 給它注入一些活力。
如何獲取電影為了獲取我們的電影,我們將使用 TVMAZE 的 API。創建main.js文件並添加以下代碼:
constget_movie=(value="Gameofthrones")=>{fetch(`https://api.tvmaze.com/singlesearch/shows?q=${value}&embed=episodes`).then((response)=>create_UI(response.json()));};我們創建了一個函數get_movie(value = "Game of thrones"),使用了 JavaScript fetch API。我們用它來向我們的電影 API 端點(endpoint)發出GET請求。
fetch API 會返回一個 promise 。為了使用 API 的響應,我們使用了.then()回調,其中我們將response.json()傳入一個新的函數create_UI()。讓我們繼續創建create_UI函數:
constcreate_UI=(data)=>{constmovie_img=document.querySelector("#img_src");constmovie_icon=document.querySelector("#img_icon");constmovie_title=document.querySelector(".movie_title");constmovie_desc=document.querySelector(".movie_desc");constmovie_link=document.querySelector(".btn");constmovie_date=document.querySelector("#movie_date");constmovie_rating=document.querySelector("#movie_rating");constmovie_runtime=document.querySelector("#movie_runtime");constmovie_status=document.querySelector("#movie_status");//設置 UImovie_icon.src=data.image.medium;movie_img.src=data.image.original;movie_title.textContent=data.name;movie_desc.innerHTML=data.summary;movie_link.href=data.officialSite;movie_date.textContent=data.premiered;movie_rating.textContent=data.rating.average;movie_runtime.textContent=data.runtime;movie_status.textContent=data.status;};上述函數,顧名思義,幫助我們為我們的電影應用程序創建用戶界面。但當然,我們仍然需要一種方法來收集用戶的電影名稱。
我們需要做的第一件事是給我們的 HTML 表單(form)添加一個onsubmit事件處理程序:
<formonsubmit="search(event)"id="header_form"><inputtype="search"class="header_form-input"placeholder="Search,PressEntertoSubmit"/>//</form>現在在我們的main.js文件中,我們通過提交表單時發生的事件觸發處理:
//handleformsubmitconstsearch=(event)=>{event.preventDefault();constvalue=document.querySelector(".header_form-input").value;get_movie(value);};當用戶提交表單時,我們就會得到他們在搜索框中輸入的值,並將其傳遞給我們先前創建的 get_movie(value = "Game of thrones")函數。
Promise 鏈與我們在之前的例子中看到的不同,.then()回調並不是真正的結束。這是因為當你返回一個 promise 的值時,你會得到另一個 promise。當你想按順序運行一系列的異步操作時,這就變得非常有用。
例如,我們的電影 API 不只是返回一部電影的信息,它還返回所有劇集的信息。比方說,我們真的不想顯示《權力的遊戲》中的所有劇集,我們只想要前四(4)集。
通過 promise chaining(鏈),我們可以很容易地實現這一點:
constget_movie=(value="Gameofthrones")=>{fetch(`https://api.tvmaze.com/singlesearch/shows?q=${value}&embed=episodes`).then((response)=>response.json()).then((data)=>{if(data._embedded.episodes.length>0){constnew_data=data._embedded.episodes.slice(0,4);create_UI(data);returncreate_episodesUI(new_data);}else{returncreate_UI(data);}});};這仍然是我們的get_movie()函數,但這次我們不是將數據傳遞給create_UI函數,而是返迴響應.then((response) => response.json())。這將創建一個新的 promise,我們可以將更多的回調添加到這個 promise 上。
理想情況下,這個鏈可以一直持續下去,只要你想。記住,你所要做的就是返回 promise 的值。
如何處理 Promises 中的錯誤在一個 promise 中發生的錯誤會立即進入 .catch()` 回調:
fetch(`https://api.tvmaze.com/singlesearch/shows?q=${value}&embed=episodes`).then((response)=>response.json()).then((data)=>{//這裡的任何錯誤都會觸發.catch()的回調。}).catch((error)=>{//所有的錯誤都在這裡被捕捉和處理}).catch()回調是.then(null, (error) => {})的簡寫。你也可以把上面的內容寫成:
fetch(`https://api.tvmaze.com/singlesearch/shows?q=${value}&embed=episodes`).then((response)=>response.json()).then((data)=>{//這裡的任何錯誤都會觸發.catch()的回調。},(error)=>{//所有的錯誤都在這裡被捕捉和處理})以我們的電影搜索應用為例,當我們遇到任何錯誤時,我們可以在.catch()回調中處理並向用戶顯示一個漂亮的錯誤信息:
constget_movie=(value="Gameofthrones")=>{fetch(`https://api.tvmaze.com/singlesearch/shows?q=${value}&embed=episodes`).then((response)=>response.json()).then((data)=>{if(data._embedded.episodes.length>0){constnew_data=data._embedded.episodes.slice(0,4);create_UI(data);returncreate_episodesUI(new_data);}else{returncreate_UI(data);}}).catch((error)=>{console.log(error.message);//挑戰:在此顯示你的錯誤});};現在,如果由於任何原因產生的一個錯誤,.catch()回調被調用,我們向用戶顯示當前的錯誤。
如何在 JavaScript 中創建 Promises現在我們已經了解了什麼是 promise 以及如何使用它們,讓我們看看如何在 JavaScript 中創建一個 promise。
要在 JavaScript 中創建一個 promise,你需要使用 promise 構造函數。構造函數需要一個參數:一個有兩個參數的函數,resolve和reject:
constis_true=trueconstnew_promise=newPromise((resolve,reject)=>{if(is_true){//一切都很順利resolve()}else{//Oops有一個錯誤reject()}})然後我們可以通過回調來使用我們的 new_promise:
new_promise.then((response)=>{//一切都很順利}).catch((error)=>{//處理錯誤});總結在本教程中,我們學習了 promise,它們是什麼,以及如何通過建立一個電影搜索應用程序來使用它們。我們的電影應用程序的全部代碼和實時預覽可以在 Codepen 上找到。電影搜索應用程序。
挑戰在創建我們的電影應用程序時,我遺漏了一些部分,我認為這些部分對你練習新的 Promise 技能很有幫助:
希望這篇文章對你有幫助。
原文鏈接:https://www.freecodecamp.org/news/javascript-promises-for-beginners/
作者:Spruce Emmanuel
譯者:luojiyin
