sleep()在ES7中利用Promise和async/await的優雅實現

sleep()的優雅實現

演示

var sleep = async (duration) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, duration);
    });
};
(async () => {
    console.log("start!"+new Date().toISOString());
    console.time("timer1");
    await sleep(2000);//阻塞該async方法的執行線程,直到sleep()返回的Promise resolve
    console.timeEnd("timer1");
    console.log("end"+new Date().toISOString());
})();
console.log("after sleep test!");

輸出

start!2017-11-11T11:25:28.834Z
after sleep test!
timer1: 2000.845947265625ms
end2017-11-11T11:25:30.838Z

可見這個定時器工作的還是不錯滴。

Promise 簡介

Promise 對象用於一個異步操作的最終完成(或失敗)及其結果值的表示,它實際上是一個執行器(executor)做下的承諾,代表執行器在執行完畢時,會返回某個值,或者在失敗時,會輸出某個錯誤狀態。

構造函數:

new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;

簡記:

new Promise<T>(/*executor*/(resolve,reject)=>{})

executor在Promise構造函數執行時同步執行,這裏承諾executor在該構造函數返回的對象之前一定會被調用。
新創建的Promise內部狀態是pending。executor內部通常會執行一些異步操作,一旦完成,可以調用resolve()函數來將promise狀態改成fulfilled,或者在發生錯誤時調用reject()方法將它的狀態改爲rejected
如果在executor函數中拋出一個錯誤,那麼該promise狀態爲rejected,executor函數的返回值被忽略。

成員方法

Promise.all(iterable);

構造一個新的Promise,需要等到iterable中所有的Promise全部調用resolve,新Promise纔會resolve,這個resolve傳遞的是所有resolve傳遞的值按照iterable中順序排列的相應返回值的數組。或者其中只要有一個調用reject,則新Promise執行reject。

Promise.race(iterable);

構造一個新的Promise,iterable中只要有一個Promise執行resolve或者reject,則新的Promise執行resolve或者reject。

Promise.reject(message);

返回一個狀態爲rejected的Promise,附帶信息。

Promise.resolve(value);

返回一個狀態爲fulfilled的Promise。

實際實現的時候,上面四個方法實際上是接口PromiseConstructor的成員方法,它們是全局變量Promise(declare var Promise: PromiseConstructor;)的調用.

原型

Promise.prototype.then(onResolved,onReject):Promise

添加肯定和否定回調到當前 promise, 返回一個新的、將以回調的返回值來resolve的promise。

Promise.prototype.catch(onRejected)

添加一個否定回調到當前promise,返回一個新的、將以回調的返回值來resolve的promise。如果當前promise執行順利,進入的狀態是fulfilled,換言之,onRejected不會被調用,則以當前promise的resolve結果作爲新的promise的resolve結果。

實際上,catch和then是接口Promise的成員方法,而全局變量Promise的接口類型PromiseConstructor持有一個readonly的屬性prototype。
看這一段代碼和文檔的時候,一定要搞清楚接口Promise和全局變量Promise的區別

async/await

async function 函數聲明將定義一個異步函數,返回 AsyncFunction 對象。

async語法:

async function name([param[, param[, … param]]]) { statements }

params description
name 函數名稱。
param 要傳遞給函數的參數的名稱。
statements 函數體語句。
- -
返回值 一個 AsyncFunction 對象,表示一個異步函數。

調用 async 函數時會返回一個 Promise 對象。當這個 async 函數返回一個值時,Promise 的 resolve 方法將會處理這個值;當 async 函數拋出異常時,Promise 的 reject 方法將處理這個異常值。

await表達式:await <promise:Promise>

await表達式只能在async方法中使用,await可以用來阻塞一個async方法的執行。直到await表達式的Promise中resolve或者reject。並且會將Promise.resolve的返回值作爲await表達式的返回值。如果Promise使用reject傳出了錯誤消息,那麼await表達式將會拋出異常。

例子

var asyncError=async (message,duration=200) => {
    return new Promise((resolve, reject) => {
        setTimeout(reject(message), duration);
    });
};

(async () => {
    let v;
    try{
        v= await asyncError("a promise reject something");
    }catch(e){
        console.log(`error is ${e}`);
    }
    console.log(`asyncError return ${v}`);
})();

輸出結果

error is a promise reject something
asyncError return undefined

更多資料:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章