首頁 web前端 js教程 使用JavaScript實現比非同步更好的解決方法?

使用JavaScript實現比非同步更好的解決方法?

Jun 13, 2018 am 11:40 AM
javascript 非同步

這篇文章主要告訴大家了JavaScript體驗非同步更好的解決辦法,有這方面需要的朋友跟著學習參考下吧。

一、非同步解決方案的演化史
JavaScript的非同步操作一直是個麻煩事,所以不斷有人提出它的各種解決方案。可以追溯到最早的回呼函數(ajax老朋友),到Promise(不算新的朋友),再到ES6的Generator(強勁的朋友)。
幾年前我們可能用過一個比較著名的Async.js,但是它沒有擺脫回呼函數,並且錯誤處理也是按照“回調函數的第一個參數用來傳遞錯誤”這樣一個約定。而眾所皆知的回調地獄仍然是一個比較突出的問題,直到Generator改變了這種非同步風格。
但是ES7的async await的出現(碉堡的新朋友),我們可以輕鬆寫出同步風格的程式碼同時又擁有非同步機制,可以說是目前最簡單,最優雅,最佳的解決方案了。

二、async await語法
async await語法比較簡單,可以認為是Generator的語法糖,比起星號和yield更具有語意化。下面一個簡單的例子表示1秒之後輸出hello world:

function timeout(ms) {
 return new Promise((resolve) => {
  setTimeout(resolve, ms);
 });
}
async function asyncPrint(value, ms) {
 await timeout(ms);
 console.log(value)
}
asyncPrint('hello world', 1000);
登入後複製

await只能用在async函數中,如果用在普通函數就會報錯

await後面跟的是一個Promise物件(當然其它值也可以,但是會包裝成一個立即resolve的Promise,也就沒有意義了)

await會等待Promise的結果返回再繼續執行

await等待的雖然是Promise對象,但是不必寫.then(),直接可以得到回傳值,將上面的程式碼微調,發現回傳值result也是可以輸出hello world:

function timeout(ms) {
 return new Promise((resolve) => {
  setTimeout(_ => {resolve('hello world')}, ms);
 });
}
async function asyncPrint(ms) {
 let result = await timeout(ms);
 console.log(result)
}
asyncPrint(1000);
登入後複製

三、async await錯誤處理

前面說了await等待的雖然是Promise對象,但是不必寫.then(),所以其實也不用寫.catch()了,直接用try catch就能捕捉錯誤,這樣可以避免錯誤處理程式碼非常冗餘餘和笨重,還是將上面的例子微調:

function timeout(ms) {
 return new Promise((resolve, reject) => {
  setTimeout(_ => {reject('error')}, ms);//reject模拟出错,返回error
 });
}
async function asyncPrint(ms) {
 try {
   console.log('start');
   await timeout(ms);//这里返回了错误
   console.log('end');//所以这句代码不会被执行了
 } catch(err) {
   console.log(err); //这里捕捉到错误error
 }
}
asyncPrint(1000);
登入後複製

如果有多個await,可以一起放在try catch中:

async function main() {
 try {
  const async1 = await firstAsync();
  const async2 = await secondAsync();
  const async3 = await thirdAsync();
 }
 catch (err) {
  console.error(err);
 }
}
登入後複製

四、async await注意點

1). 前面已經說過,await指令後面的Promise對象,運行結果很可能是reject或邏輯報錯,所以最好把await放在try catch程式碼區塊中。

2). 多個await指令的非同步操作,如果不存在依賴關係,讓它們同時觸發。

const async1 = await firstAsync();
const async2 = await secondAsync();
登入後複製

上面程式碼中,async1和async2如果是兩個獨立的非同步操作,這樣寫會比較耗時,因為只有firstAsync完成以後,才會執行secondAsync,完全可以用Promise.all優雅地處理:

let [async1, async2] = await Promise.all([firstAsync(), secondAsync()]);
登入後複製

3). await只能用在async函數之中,如果用在普通函數就會報錯:

async function main() {
 let docs = [{}, {}, {}];
 //报错 await is only valid in async function
 docs.forEach(function (doc) {
  await post(doc);
  console.log('main');
 });
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}
登入後複製

在forEach內部方法加上async就可以了:

async function main() {
 let docs = [{}, {}, {}];
 docs.forEach(async function (doc) {
  await post(doc);
  console.log('main');
 });
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}
登入後複製

但你會發現3個main是同時輸出的,這就說明post是並發執行的,而不是繼發執行,改成for就可以解決問題,3個main是分別相隔1秒輸出:

async function main() {
 let docs = [{}, {}, {}];
 for (let doc of docs) {
  await post(doc);
  console.log('main');
 }
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}
登入後複製

總之,用了async await之後整個人神清氣爽,可以用非常簡潔和優雅的代碼實現各種花式異步操作,並且在業務邏輯複雜的情況下可以不用陷入回調地獄中。不敢說這一定是終極的解決方案,但確實是目前最優雅的解決方案!

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

在Angular中如何整合zTree程式碼

node打包工具Pkg(詳細教學)

在微信中如何使用js喚起App?

以上是使用JavaScript實現比非同步更好的解決方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Python asyncio 進階指南:從初學者到專家 Python asyncio 進階指南:從初學者到專家 Mar 04, 2024 am 09:43 AM

並發和非同步編程並發編程處理同時執行的多個任務,非同步編程是一種並發編程,其中任務不會阻塞線程。 asyncio是python中用於非同步程式設計的函式庫,它允許程式在不阻塞主執行緒的情況下執行I/O操作。事件循環asyncio的核心是事件循環,它監控I/O事件並調度相應的任務。當一個協程準備好時,事件循環會執行它,直到它等待I/O操作。然後,它會暫停協程並繼續執行其他協程。協程協程是可暫停和恢復執行的函數。 asyncdef關鍵字用於建立協程。協程使用await關鍵字等待I/O作業完成。 asyncio的基礎以下

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles