日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解JavaScript Promise和Async/Await

瀏覽:26日期:2023-10-01 15:01:22
概述

一般在開發中,查詢網絡API操作時往往是比較耗時的,這意味著可能需要一段時間的等待才能獲得響應。因此,為了避免程序在請求時無響應的情況,異步編程就成為了開發人員的一項基本技能。

在JavaScript中處理異步操作時,通常我們經常會聽到 'Promise '這個概念。但要理解它的工作原理及使用方法可能會比較抽象和難以理解。

四個示例

那么,在本文中我們將會通過實踐的方式讓你能更快速的理解它們的概念和用法,所以與許多傳統干巴巴的教程都不同,我們將通過以下四個示例開始:

示例1:用生日解釋Promise的基礎知識 示例2:一個猜數字的游戲 示例3:從Web API中獲取國家信息 示例4:從Web API中獲取一個國家的周邊國家列表示例1:用生日解釋Promise基礎知識

首先,我們先來看看Promise的基本形態是什么樣的。

Promise執行時分三個狀態:pending(執行中)、fulfilled(成功)、rejected(失敗)。

new Promise(function(resolve, reject) { if (/* 異步操作成功 */) {resolve(value); //將Promise的狀態由padding改為fulfilled } else {reject(error); //將Promise的狀態由padding改為rejected }})實現時有三個原型方法then、catch、finallypromise.then((result) => { //promise被接收或拒絕繼續執行的情況}).catch((error) => { //promise被拒絕的情況}).finally (() => { //promise完成時,無論如何都會執行的情況})

基本形態介紹完成了,那么我們下面開始看看下面的示例吧。

用戶故事:我的朋友Kayo答應在兩周后在我的生日Party上為我做一個蛋糕。

如果一切順利且Kayo沒有生病的話,我們就會獲得一定數量的蛋糕,但如果Kayo生病了,我們就沒有蛋糕了。但不論有沒有蛋糕,我們仍然會開一個生日Party。

所以對于這個示例,我們將如上的背景故事翻譯成JS代碼,首先讓我們先創建一個返回Promise的函數。

const onMyBirthday = (isKayoSick) => { return new Promise((resolve, reject) => { setTimeout(() => { if (!isKayoSick) {resolve(2); } else {reject(new Error('I am sad')); } }, 2000); });};

在JavaScript中,我們可以使用new Promise()創建一個新的Promise,它接受一個參數為:(resolve,reject)=>{} 的函數。

在此函數中,resolve和reject是默認提供的回調函數。讓我們仔細看看上面的代碼。

當我們運行onMyBirthday函數2000ms后。

如果Kayo沒有生病,那么我們就以2為參數執行resolve函數 如果Kayo生病了,那么我們用new Error('I am sad')作為參數執行reject。盡管您可以將任何要拒絕的內容作為參數傳遞,但建議將其傳遞給Error對象。

現在,因為onMyBirthday()返回的是一個Promise,我們可以訪問then、catch和finally方法。我們還可以訪問早些時候在then和catch中使用傳遞給resolve和reject的參數。

讓我們通過如下代碼來理解概念

如果Kayo沒有生病

onMyBirthday(false) .then((result) => { console.log(`I have ${result} cakes`); // 控制臺打印“I have 2 cakes” }) .catch((error) => { console.log(error); // 不執行 }) .finally(() => { console.log('Party'); // 控制臺打印“Party” });

如果Kayo生病

onMyBirthday(true) .then((result) => { console.log(`I have ${result} cakes`); // 不執行 }) .catch((error) => { console.log(error); // 控制臺打印“我很難過” }) .finally(() => { console.log('Party'); // 控制臺打印“Party” });

相信通過這個例子你能了解Promise的基本概念。

示例2:一個猜數字的游戲

基本需求:

用戶可以輸入任意數字 系統從1到6中隨機生成一個數字 如果用戶輸入數字等于系統隨機數,則給用戶2分 如果用戶輸入數字與系統隨機數相差1,給用戶1分,否則,給用戶0分 用戶想玩多久就玩多久

對于上面的需求,我們首先創建一個enterNumber函數并返回一個Promise:

const enterNumber = () => { return new Promise((resolve, reject) => { // 從這開始編碼 });};

我們要做的第一件事是向用戶索要一個數字,并在1到6之間隨機選擇一個數字:

const enterNumber = () => { return new Promise((resolve, reject) => { const userNumber = Number(window.prompt('Enter a number (1 - 6):')); // 向用戶索要一個數字 const randomNumber = Math.floor(Math.random() * 6 + 1); // 選擇一個從1到6的隨機數 });};

當用戶輸入一個不是數字的值。這種情況下,我們調用reject函數,并拋出錯誤:

const enterNumber = () => { return new Promise((resolve, reject) => { const userNumber = Number(window.prompt('Enter a number (1 - 6):')); // 向用戶索要一個數字 const randomNumber = Math.floor(Math.random() * 6 + 1); //選擇一個從1到6的隨機數 if (isNaN(userNumber)) { reject(new Error('Wrong Input Type')); // 當用戶輸入的值非數字,拋出異常并調用reject函數 } });};

下面,我們需要檢查userNumber是否等于RanomNumber,如果相等,我們給用戶2分,然后我們可以執行resolve函數來傳遞一個object { points: 2, randomNumber } 對象。

如果userNumber與randomNumber相差1,那么我們給用戶1分。否則,我們給用戶0分。

return new Promise((resolve, reject) => { const userNumber = Number(window.prompt('Enter a number (1 - 6):')); // 向用戶索要一個數字 const randomNumber = Math.floor(Math.random() * 6 + 1); // 選擇一個從1到6的隨機數 if (isNaN(userNumber)) { reject(new Error('Wrong Input Type')); // 當用戶輸入的值非數字,拋出異常并調用reject函數 } if (userNumber === randomNumber) { // 如果相等,我們給用戶2分 resolve({ points: 2, randomNumber, }); } else if ( userNumber === randomNumber - 1 || userNumber === randomNumber + 1 ) { // 如果userNumber與randomNumber相差1,那么我們給用戶1分 resolve({ points: 1, randomNumber, }); } else { // 否則用戶得0分 resolve({ points: 0, randomNumber, }); }});

下面,讓我們再創建一個函數來詢問用戶是否想繼續游戲:

const continueGame = () => { return new Promise((resolve) => { if (window.confirm('Do you want to continue?')) { // 向用戶詢問是否要繼續游戲 resolve(true); } else { resolve(false); } });};

為了不使游戲強制結束,我們創建的Promise沒有使用Reject回調。

下面,我們創建一個函數來處理猜數字邏輯:

const handleGuess = () => { enterNumber() // 返回一個Promise對象 .then((result) => { alert(`Dice: ${result.randomNumber}: you got ${result.points} points`); // 當resolve運行時,我們得到用戶得分和隨機數 // 向用戶詢問是否要繼續游戲 continueGame().then((result) => {if (result) { handleGuess(); // If yes, 游戲繼續} else { alert('Game ends'); // If no, 彈出游戲結束框} }); }) .catch((error) => alert(error));}; handleGuess(); // 執行handleGuess 函數

在這當我們調用handleGuess函數時,enterNumber()返回一個Promise對象。

如果Promise狀態為resolved,我們就調用then方法,向用戶告知競猜結果與得分,并向用戶詢問是否要繼續游戲。

如果Promise狀態為rejected,我們將顯示一條用戶輸入錯誤的信息。

不過,這樣的代碼雖然能解決問題,但讀起來還是有點困難。讓我們后面將使用async/await 對hanldeGuess進行重構。

網上對于 async/await 的解釋已經很多了,在這我想用一個簡單概括的說法來解釋:async/await就是可以把復雜難懂的異步代碼變成類同步語法的語法糖。

下面開始看重構后代碼吧:

const handleGuess = async () => { try { const result = await enterNumber(); // 代替then方法,我們只需將await放在promise前,就可以直接獲得結果 alert(`Dice: ${result.randomNumber}: you got ${result.points} points`); const isContinuing = await continueGame(); if (isContinuing) { handleGuess(); } else { alert('Game ends'); } } catch (error) { // catch 方法可以由try, catch函數來替代 alert(error); }};

通過在函數前使用async關鍵字,我們創建了一個異步函數,在函數內的使用方法較之前有如下不同:

和then函數不同,我們只需將await關鍵字放在Promise前,就可以直接獲得結果。 我們可以使用try, catch語法來代替promise中的catch方法。

下面是我們重構后的完整代碼,供參考:

const enterNumber = () => { return new Promise((resolve, reject) => { const userNumber = Number(window.prompt('Enter a number (1 - 6):')); // 向用戶索要一個數字 const randomNumber = Math.floor(Math.random() * 6 + 1); // 系統隨機選取一個1-6的數字 if (isNaN(userNumber)) { reject(new Error('Wrong Input Type')); // 如果用戶輸入非數字拋出錯誤 } if (userNumber === randomNumber) { // 如果用戶猜數字正確,給用戶2分 resolve({points: 2,randomNumber, }); } else if ( userNumber === randomNumber - 1 || userNumber === randomNumber + 1 ) { // 如果userNumber與randomNumber相差1,那么我們給用戶1分 resolve({points: 1,randomNumber, }); } else { // 不正確,得0分 resolve({points: 0,randomNumber, }); } });}; const continueGame = () => { return new Promise((resolve) => { if (window.confirm('Do you want to continue?')) { // 向用戶詢問是否要繼續游戲 resolve(true); } else { resolve(false); } });}; const handleGuess = async () => { try { const result = await enterNumber(); // await替代了then函數 alert(`Dice: ${result.randomNumber}: you got ${result.points} points`); const isContinuing = await continueGame(); if (isContinuing) { handleGuess(); } else { alert('Game ends'); } } catch (error) { // catch 方法可以由try, catch函數來替代 alert(error); }}; handleGuess(); // 執行handleGuess 函數

我們已經完成了第二個示例,接下來讓我們開始看看第三個示例。

示例3:從Web API中獲取國家信息

一般當從API中獲取數據時,開發人員會精彩使用Promises。如果在新窗口打開https://restcountries.eu/rest/v2/alpha/cn,你會看到JSON格式的國家數據。

通過使用Fetch API,我們可以很輕松的獲得數據,以下是代碼:

const fetchData = async () => { const res = await fetch('https://restcountries.eu/rest/v2/alpha/cn'); // fetch() returns a promise, so we need to wait for it const country = await res.json(); // res is now only an HTTP response, so we need to call res.json() console.log(country); // China’s data will be logged to the dev console}; fetchData();

現在我們獲得了所需的國家/地區數據,讓我們轉到最后一項任務。

示例4:從Web API中獲取一個國家的周邊國家列表

下面的fetchCountry函數從示例3中的api獲得國家信息,其中的參數alpha3Code 是代指該國家的國家代碼,以下是代碼

// Task 4: 獲得中國周邊的鄰國信息const fetchCountry = async (alpha3Code) => { try { const res = await fetch( `https://restcountries.eu/rest/v2/alpha/${alpha3Code}` ); const data = await res.json(); return data; } catch (error) { console.log(error); }};

下面讓我們創建一個fetchCountryAndNeighbors函數,通過傳遞cn作為alpha3code來獲取中國的信息。

const fetchCountryAndNeighbors = async () => { const china= await fetchCountry('cn'); console.log(china);}; fetchCountryAndNeighbors();

在控制臺中,我們看看對象內容:

詳解JavaScript Promise和Async/Await

在對象中,有一個border屬性,它是中國周邊鄰國的alpha3codes列表。

現在,如果我們嘗試通過以下方式獲取鄰國信息。

const neighbors =china.borders.map((border) => fetchCountry(border));

neighbors是一個Promise對象的數組。

當處理一個數組的Promise時,我們需要使用Promise.all。

const fetchCountryAndNeigbors = async () => { const china = await fetchCountry('cn'); const neighbors = await Promise.all( china.borders.map((border) => fetchCountry(border)) ); console.log(neighbors);}; fetchCountryAndNeigbors();

在控制臺中,我們應該能夠看到國家/地區對象列表。

詳解JavaScript Promise和Async/Await

以下是示例4的所有代碼,供您參考:

const fetchCountry = async (alpha3Code) => { try { const res = await fetch( `https://restcountries.eu/rest/v2/alpha/${alpha3Code}` ); const data = await res.json(); return data; } catch (error) { console.log(error); }}; const fetchCountryAndNeigbors = async () => { const china = await fetchCountry('cn'); const neighbors = await Promise.all( china.borders.map((border) => fetchCountry(border)) ); console.log(neighbors);}; fetchCountryAndNeigbors();總結

完成這4個示例后,你可以看到Promise在處理異步操作或不是同時發生的事情時很有用。相信在不斷的實踐中,對它的理解會越深、越強,希望這篇文章能對大家理解Promise和Async/Await帶來一些幫助。

以下是本文中使用的代碼:https://files.cnblogs.com/files/powertoolsteam/Promise-Async-Await-main.zip

以上就是詳解JavaScript Promise和Async/Await的詳細內容,更多關于JavaScript Promise和Async/Await的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美激情91| 欧美一区网站| 日韩欧美不卡| 中文字幕高清在线播放| 国产精品毛片一区二区在线看| 国产一区福利| 欧美日韩视频网站| 蜜桃av.网站在线观看| 国产福利亚洲| 精品久久中文| 国产在线观看www| 久久伦理在线| 久热精品在线| 日韩精品亚洲专区在线观看| 日韩精品中文字幕一区二区| 国产探花一区二区| 国内自拍视频一区二区三区| 韩国三级一区| 亚洲专区一区| 91欧美日韩在线| 久久99国产精品视频| 日韩精品2区| 在线亚洲自拍| 亚洲欧美一区在线| 久久av一区| 国产九一精品| 久久久精品日韩| 久久国产精品久久w女人spa| 欧美欧美黄在线二区| 97精品97| 石原莉奈在线亚洲二区| 国产欧美一区| 久久青草久久| 日韩在线一二三区| 国产精品一区二区三区四区在线观看| 91欧美在线| 中日韩男男gay无套| 青青在线精品| 久久只有精品| 欧美日韩国产传媒| 日韩高清在线不卡| 日韩88av| 国产精品美女| 国产精品成人3p一区二区三区| av高清一区| 日韩精品a在线观看91| 正在播放日韩精品| 亚洲精品一区二区在线播放∴| 日韩成人精品一区| 西西人体一区二区| 国产精品久久久久9999高清| 欧美日韩在线观看视频小说| 奇米色欧美一区二区三区| 国模精品一区| 亚洲综合专区| 性欧美videohd高精| 88久久精品| 久久精品亚洲欧美日韩精品中文字幕| 亚洲精一区二区三区| av在线资源| 日韩av不卡一区二区| 国产99亚洲| 久久精品伊人| 蜜桃传媒麻豆第一区在线观看 | 国产精品日韩欧美一区| 麻豆一区二区三| 激情综合自拍| 开心激情综合| 中文字幕一区二区三区在线视频| 激情久久一区二区| 伊人www22综合色| 国产白浆在线免费观看| 日本精品在线播放| 中文在线一区| 成人av三级| 国产欧美在线观看免费| 久久99伊人| 91精品国产91久久久久久黑人| 国产午夜久久av| 亚洲一区二区三区四区电影| 99视频精品全国免费| 国产精品啊v在线| 中文字幕一区二区三区四区久久| 亚洲成人国产| 成人午夜网址| 国产日韩欧美一区二区三区在线观看 | 日韩和欧美一区二区| 亚洲午夜久久久久久尤物 | 久久激情五月激情| 蜜臀av性久久久久蜜臀aⅴ四虎| 色天使综合视频| 久久99国产精品视频| 国产精品视频一区二区三区 | 国产精品免费大片| 亚洲毛片在线| 久久福利影视| 亚洲一区国产| 亚洲香蕉网站| 日韩精品一区二区三区免费观看| 国产精品成人一区二区不卡| 欧美激情视频一区二区三区在线播放| 综合精品一区| 视频在线观看91| 久久www成人_看片免费不卡| 国产高清一区| 欧美aa国产视频| 欧美午夜精彩| 精品欧美久久| 亚洲成av人片一区二区密柚 | 久久免费影院| 麻豆精品久久久| 国产精品蜜月aⅴ在线| 国产亚洲字幕| 国产高清精品二区| 免费在线欧美黄色| 欧美日韩一视频区二区| 日韩精品三级| 日本成人中文字幕| 日本欧美在线| 国产欧美日韩亚洲一区二区三区| 久久精品xxxxx| 国产私拍福利精品视频二区| 欧美日本三区| 麻豆国产欧美一区二区三区| 欧美交a欧美精品喷水| 欧美精品成人| 四虎成人av| 久久久水蜜桃av免费网站| 欧美日韩国产v| 国产真实久久| 欧美日韩一二| 亚洲一区欧美激情| 综合激情视频| 欧美日韩一区二区三区不卡视频| 国产人成精品一区二区三| 欧美激情亚洲| 不卡专区在线| 私拍精品福利视频在线一区| 极品日韩av| 视频一区在线视频| 91亚洲精品在看在线观看高清| 国产精品男女| sm捆绑调教国产免费网站在线观看| 日韩久久精品| 亚洲精品2区| 在线观看视频免费一区二区三区| 亚洲aⅴ网站| 国产精品v亚洲精品v日韩精品| 精品国产一区二| 国产字幕视频一区二区| 综合视频一区| 国产激情综合| 久久精品青草| 亚洲色图国产| 另类综合日韩欧美亚洲| 久久夜夜操妹子| 久久国产高清| 国产精品久久亚洲不卡| 日韩欧美字幕| 欧美资源在线| 国产一区 二区| 日韩成人精品一区| 野花国产精品入口| 国产欧美高清视频在线| 成人日韩在线| 中文字幕一区二区av| 国产劲爆久久| 亚洲国产综合在线看不卡| 日韩中文字幕视频网| 国产一区二区三区不卡av| 亚洲激精日韩激精欧美精品| 亚洲精品影视| 高清一区二区| 在线精品一区二区| 福利一区二区免费视频| 在线综合欧美| 欧美a一区二区| 国产亚洲精品久久久久婷婷瑜伽| 国产欧美在线| 久久中文字幕av| 91精品国产自产在线丝袜啪| 亚洲三级欧美| 亚洲精品国产日韩| 日韩精品电影| 日本a口亚洲| 久久婷婷丁香| 欧美日韩1区2区3区| 欧美日韩在线二区| 欧美午夜三级| 黄页网站一区| 国产精品草草| 国产亚洲精品自拍| 精品国产成人| 亚洲视频国产精品| 午夜欧美巨大性欧美巨大| 欧美在线日韩| 在线一区视频| 日韩视频网站在线观看| 久久国产乱子精品免费女| 狠狠久久婷婷|