大家可以将Promise理解为JS的一个承诺,也就是对异步操作的一个承诺,咱先不管异步操作是否能够执行成功,使用Promise的所有异步操作,JS已经承诺处理了,咱就通过Promise的状态来知晓异步操作的执行结果。
一个 Promise有以下几种状态:
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 表示着操作完成,状态成功。
rejected: 意味着操作失败。
pending 状态的 Promise 对象可能会变为fulfilled 状态并传递一个值给相应的状态处理方法,也可能变为失败状态(rejected)并传递失败信息。当其中任一种情况出现时,Promise 对象的 then 方法绑定的处理方法(handlers )就会被调用
上文提到Promise的原型中的函数then,then可以接收2个参数(resolve [,reject])
第一个参数resolve 是对成功的一个处理,类型为Function。你可以在其中做 一些异步成功后的操作
第二个参数reject是对失败的一个处理,类型为Function。你可以在其中做 一些异步失败后的操作
一般情况下then我们只会传一个参数,也就是默认的成功处理,失败处理会使用 catch函数
catch函数只有一个参数,也就是代表失败的reject
来看看then catch的使用案例
function show(params) { //正常的请求成功操作 request('这是请求参数').then( resolve => { console.log(resolve); } ) //在then里面同时做成功和失败的操作 request('这是请求参数').then( resolve => { //这儿是成功 console.log(resolve); }, reject => { //这儿是失败 console.log(reject); } ) //正常的请求失败操作 request('这是请求参数').catch( reject => { console.log(reject); } ) } /** * 模拟发起一个http请求 * @param {object} data 请求的参数 * @param {function} callBack 回调函数 */ function request(data) { return new Promise( (resolve, reject) => { //下面的定时器模拟请求时间 setTimeout(data => { // resolve('请求成功') reject('请求失败') }, 1000); } ) } show()
使用 Promise 能够使你的异步操作变得更加优雅,可读性也比较高,同时,Promise在ES6的各大插件中也使用的相当广泛,所以掌握 Promise是非常有必要的
二.async / await
想详细了解更多,请移步
async关键字用来定义一个function,用来标识此函数是一个异步函数
切记 切记 切记, await 关键字仅仅在 async function中有效。如果在 async function函数体外使用 await ,你只会得到一个语法错误SyntaxError
async关键字放在函数的声明之前,例如:
async function test() { } async () => { } async data => { } class Test { async show() { } }
无论是普通的函数,Lambda表达式,或是ES6的class,该关键字都是放置在函数的声明之前
在调用声明了async的函数时,会返回一个Promise对象
而await关键字则是放置在异步操作的调用之前,await会使得async函数在执行到异步操作时暂停代码执行,直到异步操作返回的Promise状态更改为 fulfilled 或 rejected,此时代码会继续执行,并自动解析Promise返回的值,无论是成功还是失败,都会解析到await关键字前面定义接收的参数,请看例子:
class Test { /** * 线程休眠 * @param {number} timer 休眠毫秒数 */ Sleep(timer) { return new Promise( resolve => { setTimeout(() => { resolve(timer) }, timer); } ) } } let T = new Test(); async function show() { console.log('第一次'); await T.Sleep(1000) console.log('第二次'); } show()
上面的实例调用show函数,会立即打印出 第一次,延时1000毫秒后,会打印出 第二次
原理嘛,就是模仿Java的线程休眠函数Sleep
在打印了 第一次 后,会调用T的Sleep函数,Sleep函数返回了一个Promise,在定时器执行完毕后调用Promise的resolve函数,会将Promise 的状态更改为 fulfilled,此时await检测到Promise的状态更改,继续执行代码,输出 第二次
三 . generator
generator(生成器)是ES6标准引入的新的数据类型,使用方式是在函数名前加上*,generator和普通的函数差不多,但是可以返回多次。
嗯,所有的函数都有默认的返回值,如果没有明确定义,那就会返回undefined,generator也不例外!
generator使用yield关键字来中途返回值,请看案例