Docker 的優點
750
2025-04-02
Promise 是一個 ECMAScript 6 提供的類,
Async/await 是 ECMAScript 7 新增的內容,
兩者目的都是為了更加優雅地書寫復雜的異步任務。
此處介紹她們關于后面小程序開發所需要主要內容,更為詳細內容請參考手冊、文檔。
我們都知道JS是一個單線程的語言,一次只能執行一個任務,如果碰到時間較長任務,會被拖到任務隊列等待其他任務完成后再執行。但是類似于向后臺請求數據操作,后面的數據處理任務依賴于請求數據的完整性,由于網絡情況、服務端數據處理能力,數據包大小,可能并未得到完整數據就執行了后面的數據處理任務,出現意想不到的結果。為了保證數據獲取的完整性,有必要使用異步操作。
回調地獄
如果需要多次調用異步函數,例如,如果我想分三次輸出字符串,第一次間隔 1 秒,第二次間隔 2 秒,第三次間隔 3 秒:
setTimeout(function () { console.log("First"); setTimeout(function () { console.log("Second"); setTimeout(function () { console.log("Third"); }, 3000); }, 2000); }, 1000);
如果調用嵌套的增加,代碼層次變得更深,無論是維護還是異常處理難度也隨之增加,尤其是我們使用的是可能包含了很多循環和條件語句的真實代碼。這些容易使人迷茫的異步回調編寫方式被稱為“回調地獄”或“厄運金字塔”。
而Promise可以通過使每個行為都成為一個獨立的函數來嘗試減輕這種問題
Promise
Promise 對象的構造器(constructor)語法如下:
let promise = new Promise(function(resolve, reject) { // executor });
傳遞給 new Promise 的函數被稱為 executor。當 new Promise 被創建,executor 會自動運行。
它的參數 resolve 和 reject 是由 JavaScript 自身提供的回調。我們的代碼僅在 executor 的內部。
當 executor 獲得了結果,無論是早還是晚都沒關系,它應該調用以下回調之一:
resolve(value) — 如果任務成功完成并帶有結果 value。
reject(error) — 如果出現了 error,error 即為 error 對象。
所以總結一下就是:executor 會自動運行并嘗試執行一項工作。嘗試結束后,如果成功則調用 resolve,如果出現 error 則調用 reject。
由 new Promise 構造器返回的 promise 對象具有以下內部屬性:
Promise有三種狀態state
最初是 "pending",然后在 resolve 被調用時變為 "fulfilled",或者在 reject 被調用時變為 "rejected"。
三種事件狀態由"pending"變為 "fulfilled"或"rejected"后不可倒流回"pending"狀態
比如:學校要舉行期末考試,等待考試狀態是"pending",成功開展考試變是 "fulfilled",由于疫情原因小伙伴們提前撤退沒有參與考試是"rejected",都不再回到等待考試狀態。
每一種狀態會對應result結果
result 最初是 undefined,然后在 resolve(value) 被調用時變為 value,或者在 reject(error) 被調用時變為 error。
等待時undefined,成功開展考試可以得到各個學生的試卷內容resolve(value),或者沒能舉辦考試得到開展失敗reject(error)的記錄
所以,executor 最終將 promise 移至以下狀態之一:
Promise.all()與Promise.race()
Promise.all()
微信發朋友圈時,想上傳9張圖片到云存儲,類似這種等待所有事件完成再執行后續操作一般使用Promise.all()
以下是對成功 fulfulled 的 promise 使用.then做出的反應:
setTimeout(code/function, milliseconds, param1, param2, ...)用于在指定的毫秒數后調用函數或計算表達式。
Promise.all()會等待數組里面所有promise的executor 運行完畢后再以.then()處理
例如,以下是對失敗 rejected 的 promise 使用.catch做出的反應:
Promise.all()會等待數組里面所有promise的executor 運行一旦執行reolve()回調則認為事物失敗,再以.catch()處理,且腳b本程序可繼續執行。
Promise.race()
Promise.race()[p1,p2])只要有一個請求完成就會觸發后面.then(),
常用于判斷請求是否超時
比如p1事件,p2是個定時器,如果先執行p2,就可以知道p1超時了,該做些其他操作。
Async/Await
在云函數里,由于 Node 版本最低是 8.9,因此是天然支持 async/await 語法的。而在小程序舊版本則不然。
兩種方式解決:
①直接改變基礎庫環境,到新版本
②配置相關工具,需要下載并引入額外的文件。可把這個 regenerator/runtime.js 文件引用到有使用 async/await 的文件當中。手動import regeneratorRuntime
https://gitee.com/longyorke/miniprogram_async_await/tree/master/
Async
在函數前面的 “async” 這個單詞表達了一個簡單的事情:即這個函數總是返回一個 promise。其他值將自動被包裝在一個 resolved 的 promise 中。
下面這個函數返回一個結果為1的 resolved promise,
async function f() { return 1; } f().then(alert); // 1
等效于
async function f() { return Promise.resolve(1); } f().then(alert); // 1
Await
關鍵字 await 讓 JavaScript 引擎等待直到 promise 完成(settle)并返回結果。
只在 async 函數內工作
(async () => { await this.example(); })()
這里的例子就是一個 1 秒后 resolve 的 promise,alert的內容需要等待完整的信息傳入:
async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // 等待,直到 promise resolve alert(result); // "done!" } f();
await 使得不會進行后面依賴函數的執行,直到 promise 狀態變為 settled,然后以 promise 的結果繼續執行。
在page.js中我們一般把函數定義放在鉤子回調函數同層級下,在生命周期函數里面執行
onLoad: function (options) { console.log(this.example()) }, async example(){ console.log("example") return 1 },
相比于 promise.then,它只是獲取 promise 的結果的一個更優雅的語法,同時也更易于讀寫。
async/await 可以和 Promise.all 一起使用
// 等待結果數組 let results = await Promise.all([ require(url1), require(url2), ... ]);
如果出現 error,也會正常傳遞,從失敗了的 promise 傳到Promise.all,然后變成我們能通過使用try..catch在調用周圍捕獲到的異常(exception)。
使用try..catch,如果有 error 發生,執行控制權馬上就會被移交至catch塊。
async function f() { try { const rp = require("request-promise") let response = await rp('/no-user-here'); let user = await response .json(); } catch(err) { // 捕獲到 rp和 response.json 中的錯誤 alert(err); } } f();
如果我們沒有try..catch,發生錯誤后,那么由異步函數f()的調用生成的 promise 狀態為 rejected。我們可以在函數調用后面添加.catch來處理這個 error:
async function f() { const rp = require("request-promise") let response = await rp('/no-user-here'); } // f() 變成了一個 rejected 的 promise f().catch(alert); // TypeError: failed to fetch // (*)
async/await是基于 promise 的,因此我們可以同時使用promise.then/catch與async/await
async await JavaScript Promise 小程序
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。