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

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