厭倦了理清 JAVAScript 或 TypeScript 項(xiàng)目中的異步代碼?
您是否希望有一種方法可以使您的異步進(jìn)程像運(yùn)轉(zhuǎn)良好的機(jī)器一樣運(yùn)行? 如果是這種情況,我們?yōu)槟峁┝艘粋€(gè)解決方案:promises - 任何出色的異步配方中的關(guān)鍵成分。 它們讓您以更有序和更易于理解的方式管理異步操作,讓您專注于編碼的更有趣的方面。 我們將在本文中帶您游覽狂野而美麗的promises世界。
什么是promise?
什么是承諾?
在 JavaScript 中,promise 是一種以更有條理、更易于理解和更簡(jiǎn)潔的方式處理異步操作的方法。 它們使您能夠構(gòu)建以可預(yù)測(cè)的順序方式運(yùn)行的代碼,即使操作本身是并行發(fā)生的。
Promise 是通過將函數(shù)作為參數(shù)傳遞給 Promise 構(gòu)造函數(shù)來創(chuàng)建的。 這個(gè)函數(shù)被稱為執(zhí)行函數(shù),它負(fù)責(zé)執(zhí)行異步操作。 執(zhí)行函數(shù)有兩個(gè)參數(shù):resolve 和 reject。 這些功能用于履行(解決)或拒絕承諾。
以下面的例子為例,其中一個(gè)承諾是用一個(gè)等待 3 秒的執(zhí)行函數(shù)創(chuàng)建的,然后用“Hey!My name is Bruno.”的值解析promise:
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hey!My name is Bruno.");
}, 3000);
});
在創(chuàng)建承諾后,您可以使用 then() 方法來告訴它在解決或拒絕時(shí)做什么。 作為參數(shù),它需要兩個(gè)函數(shù):一個(gè)用于 resolve 分支,一個(gè)用于 refuse 分支。
考慮以下場(chǎng)景,其中 resolve 分支打印消息“Hey!My name is Bruno.”,而 reject 分支在另一方面記錄一條錯(cuò)誤消息:
myPromise.then(
(message) => {
console.log(`The promise has been resolved: ${message}`)
},
(error) => {
console.log(`The promise has been rejected: ${error}`)
}
);
? 鏈接promises
鏈接promise允許您創(chuàng)建一系列異步操作,這些操作按順序/一個(gè)接一個(gè)地執(zhí)行。
myPromise
.then((message) => {
console.log(message); // Hey!My name is Bruno.
return message + " I am a software developer."
})
.then((message) => {
console.log(message); // Hey!My name is Bruno. I am a software developer.
})
上面的prmise是鏈接的,第一個(gè) then() 記錄消息的第一個(gè)版本,而第二個(gè) then() 記錄與 return 語句中的字符串連接的消息。
現(xiàn)在讓我們繼續(xù)討論 promise 的一些用例。
你可以在哪里使用promise?
在不同的情況和場(chǎng)景中,可以使用 promises 來執(zhí)行異步操作。
處理 HTTP 請(qǐng)求
可以以一種干凈且易于理解的方式處理 HTTP 請(qǐng)求。 我們將使用 AxIOS 庫(kù)來說明一個(gè)示例,它基本上與已經(jīng)內(nèi)置的 fetch() 執(zhí)行相同的操作:
import axios from "axios";
const API_URL = "dummyapithatdoesnotexist.com/data";
axios.get(API_URL)
.then((response) => response.json())
.then((jsonData) => console.log(jsonData)) // data from the API
.catch((error) => console.log(`There has been an error: ${error}`));
請(qǐng)注意 promise 末尾的“catch()”方法。“catch()”用于處理在嘗試解析 promise 時(shí)發(fā)生的任何錯(cuò)誤。 它非常有價(jià)值,也是異步操作的一個(gè)重要方面,因?yàn)樗峁┝藶槭裁此鼈儧]有成功的上下文(例如,當(dāng)沒有互聯(lián)網(wǎng)連接或服務(wù)器關(guān)閉時(shí))。
當(dāng)然還有其他場(chǎng)景可以使用 promises,但這個(gè)場(chǎng)景很好地說明了一個(gè)廣為人知的場(chǎng)景。
JavaScript 和Typescript中的Promise
您現(xiàn)在可能會(huì)問自己:但是……JavaScript 和 Typescript 中的 promises 有什么區(qū)別?
好吧,當(dāng)然,這是一個(gè)很好的問題,我們現(xiàn)在將討論這個(gè)問題。
為了創(chuàng)建承諾,JavaScript 和 TypeScript 都使用 Promise 構(gòu)造函數(shù),并且兩種語言都使用 then() 方法來指示在解決或拒絕承諾時(shí)應(yīng)該發(fā)生什么。
JavaScript 承諾和 TypeScript 承諾之間的一個(gè)重要區(qū)別是,在 TypeScript 中,您使用更強(qiáng)大的類型檢查,這有助于防止代碼中的錯(cuò)誤和錯(cuò)誤。 這可以避免在一天結(jié)束前一直頭痛的困擾(到底哪里錯(cuò)了?)。 更強(qiáng)的類型允許您聲明 promise 將解析或拒絕的值類型,而 JavaScript 依賴于運(yùn)行時(shí)類型檢查。 這是在項(xiàng)目中使用 JavaScript 或 Typescript 時(shí)要牢記的一個(gè)重要方面。
Typescript 中類型化承諾的示例如下所示:
import axios from "axios";
const API_URL: string = "dummyapithatdoesnotexist.com/data";
const myPromise: Promise<string> = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hey!My name is Bruno.");
}, 3000);
});
在指定 then() 和 catch() 場(chǎng)景時(shí),您還可以按以下方式鍵入它們:
import axios from "axios";
const API_URL: string = "dummyapithatdoesnotexist.com/data";
axios.get(API_URL)
.then((response: Response) => response.json())
.then((jsonData: any) => console.log(jsonData)) // data from the API
.catch((error: any) => console.log(`There has been an error: ${error}`));
在 Typescript 中,您還可以使用 async 和 await,前者允許您指示操作是異步的,后者會(huì)暫停函數(shù)的執(zhí)行,直到 promise 得到解決。
import axios from 'axios';
const API_URL: string = 'dummyapithatdoesnotexist.com/data';
async function getData() {
try {
const response: AxiosResponse = await axios.get(API_URL);
const jsonData: any = response.data;
console.log(jsonData);
} catch (error) {
console.log(`There has been an error: ${error}`);
}
}
getData(); // logs the data from the API
AxiosResponse 類型是從 axios 庫(kù)中導(dǎo)入的,用于鍵入本示例中的響應(yīng)變量。 要從 API 響應(yīng)中獲取 JSON 數(shù)據(jù),請(qǐng)使用 response.data 屬性。 jsonData 變量是 any 類型,表明它可以保存任何類型的值。 error 變量的類型也為 any,暗示它也可能是任何類型。
async 關(guān)鍵字將 getData() 函數(shù)標(biāo)識(shí)為異步函數(shù),而 await 關(guān)鍵字暫停函數(shù)的執(zhí)行,直到承諾得到解決。 如果在請(qǐng)求期間發(fā)生錯(cuò)誤,catch() 塊會(huì)檢測(cè)到錯(cuò)誤并將其記錄到控制臺(tái)。
感謝您的閱讀!
在了解了 JavaScript 和 Typescript 中所有這些 promises 的點(diǎn)點(diǎn)滴滴之后,您現(xiàn)在應(yīng)該能夠在代碼中以非類型化或類型化的方式應(yīng)用它們。 恭喜,希望對(duì)您有所幫助!