AI智能
改变未来

Promise,Generator,async/await学习总结基本用法


promise

首先,

promise

是一种更优的异步编程解决方案,如果我们直接使用传统的回调方式去解决异步流程,就会避免不了大量的回调函数嵌套,形成

回调地狱

,

ajax.get(url,function(data1){ajax.get(url,data1,function(data2){ajax.get(url,data2,function(data3){ajax.get(url,data3,function(data4){//...形成回调地狱})})})})

为了解决回调地狱的问题,commonjs社区率先提出了promise规范,在ESMA2015中被标准化成为了语言规范。

promise就是一个对象,用来表示一个异步任务,结束以后是成功还是失败。
promise一共有三个状态,

pending(待定状态)

fulfilled(成功状态)

rejected(失败状态)

状态只能有pending到fulfilled,或者pending到rejected,且状态是不可逆的。
promise中有一个then方法,用来接收回调后的结果,then方法中有两个参数,第一个参数是

成功

的回调,第二个参数是

失败

的回调。

基本用法:

const promise = new Promise((resolve,reject)=>{//这里用于兑现承诺resolve(\"成功拉!!\") // 兑现成功//reject(new Error(\"失败拉!!\")) // 兑现失败})promise.then((value)=>{console.log(value) //输出的成功的值},error=>{//console.log(error) //输出的失败的值})

promise配合ajax使用案列:

//封装ajaxfunction ajax(url){return new Promise(function(resolve,reject){var xhr = new XMLHttpRequest()xhr.open(\'GET\',url)xhr.responseType =\'json\'xhr.onload=function(){if(this.status===200){//代表成功resolve(this.response)}else{reject(new Error(this.statusText))}}xhr.send()})}//使用ajax(\'/api/test.json\').then(data=>{console.log(data) //请求成功的结果},reason=>{console.log(reason) //请求失败的原因})

promise的链式调用

用来解决回调地狱的问题,是我们的代码更加的扁平化。

上面的代码可以这样使用:

//使用ajax(\'/api/test.json\').then(data=>{console.log(data)//请求成功的结果//promise 对象的then方法会返回一个全新的peomise对象return ajax(\'/api/test2.json\')  //返回第二个url请求的结果},reason=>{console.log(reason) //第一个url错误的捕获})//后面的then方法就是为上一个then返回的promise注册回调.then((test2)=>{ //前面的then方法的返回值会作为后面then方法的回调的参数console.log(test2) //输出的为第二个url返回的结果return ajax(\'/api/test3.json\')  //返回第三个url请求的结果}).then((test2)=>{console.log(test2) //输出的为第三个url返回的结果})//....

Promise的异常处理

  1. 我们可以一层一层的捕获:
ajax(\'/api/test.json\').then(data=>{console.log(data)return ajax(\'/api/test2.json\')},reason1=>{console.log(reason1)//捕获url1的请求错误}).then((test2)=>{console.log(test2)return ajax(\'/api/test3.json\')},reason2=>{console.log(reason2)//捕获url2的请求错误}).then((test2)=>{console.log(test2)},reason3=>{console.log(reason3)//捕获url3的请求错误})
  1. 可以使用promise提供的catch对我们的请求进行捕获
ajax(\'/api/test.json\').then(data=>{console.log(data)return ajax(\'/api/test2.json\')}).catch((reason)=>{console.log(reason)})实际上 catch 方法就相当于我们的then方法的第一个值传入了undefinedajax(\'/api/test.json\').then(data=>{console.log(data)return ajax(\'/api/test2.json\')}).then((undefined,reason)=>{console.log(reason)})

catch这种方式更适用于

链式调用

,它可以捕获到每次then回调的错误结果,我们可以这样用:

ajax(\'/api/test.json\').then(data=>{console.log(data)return ajax(\'/api/test1.json\')}).then(data=>{console.log(data)return ajax(\'/api/test2.json\')}).catch((reason)=>{console.log(reason) //1和2有一个发生错误都会捕获到})

Promise中的静态方法

1.resolve() 快速创建一个成功的对象

Promise.resolve(\'33\').then((value)=>{console.log(value)})这种写法等同于:new Promise((resolve,reject)=>{resolve(\"成功拉!!\")})
  1. reject() 快速创建一个失败的promise对象
Promise.reject(new Error(\'失败!!!\')).then((value)=>{console.log(value)})

Promise.all()

promise并行执行的方法

Promise.all()

这个方法可以将

多个promise

合并为

一个promise

统一进行管理

Promise.all()

方法接收的是一个

数组

,数组中的每一个元素是一个

promise对象

,我们可以把这些promise对象看作是一个个的

promise任务

Promise.all()

方法会返回一个

全新的promise对象

所有的promise

都完成过后,我们返回的全新的promise才会完成,成功的返回的是一个

数组

,包含了每一个promise对象成功返回的结果

如果

有一个promise失败

了,这个promise.all()就会以

失败

结束

var promise = new Promise.all([ajax(\'/api/test1.json\'),ajax(\'/api/test2.json\'),ajax(\'/api/test3.json\')])promise.then(value=>{//所有的promise都完成过后,才会打印value//value为一个数组}).catch(err=>{console.log(err) //有一个失败就会被捕获到错误信息})

Promise.race()

Promise.race()也是把多个promise组合到一起的方法

与promise.all()的相同点:
都是传递一个数组

不同点:

promise.all()等待所有任务结束才会结束,Promise.race()只会等待第一个结束的任务,就是说Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态

let p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(\'success\')},1000)})let p2 = new Promise((resolve, reject) => {setTimeout(() => {reject(\'failed\')}, 500)})Promise.race([p1, p2]).then((result) => {console.log(result) //}).catch((error) => {console.log(error)  // 打印的是 \'failed\'})

Generator

generator(生成器)是ES6标准引入的新的数据类型,它是一种更优的异步编程解决方案。

基本用法:跟普通函数声明时的区别是加了一个*号

function *foo(){console.log(\"generator\")}foo()

上面的代码并不会执行,我们只有调用foo()函数的next()方法才会执行foo函数

function *foo(){console.log(\"generator\")}foo().next() // generator

通过yield语句可以在生成器函数内部暂停代码的执行使其挂起,此时生成器函数仍然是运行并且是活跃的,其内部资源都会保留下来,只不过是处在暂停状态。
在迭代器上调用next()方法可以使代码从暂停的位置开始继续往下执行。

function *foo(){const res =  yield \"keke\"console.log(res) //ff next方法传递过来的值}}const generator = foo()const result = generator.next() //result表示接收到的值console.log(result)//{ value: \'keke\', done: false }generator.next(\"ff\")

用generator进行异步操作处理:

function ajax(url){return new Promise(function(resolve,reject){var xhr = new XMLHttpRequest()xhr.open(\'GET\',url)xhr.responseType=\'json\'xhr.onload=function(){if(this.status===200){//代表成功resolve(this.response)}else{reject(new Error(this.statusText))}}xhr.send()})}**使用 generator 处理异步:**function *main(){//使用try catch捕获异常try{const url = yield ajax(\'/api/test.json\')console.log(url) //拿到返回值}catch(err){console.log(err)}}const generator = main()const result = generator.next()//result.value是一个promise对象,我们可以调用then方法获取dataresult.value.then((data)=>{generator.next(data)},reason=>{generator.throw(new Error(reason)) //捕获到错误扔出})

处理多个异步

function* main() {try {const url = yield ajax(\'/api/test.json\')console.log(url) //拿到url返回值const url2 = yield ajax(\'/api/test2.json\')console.log(url2) //拿到url2返回值const url3 = yield ajax(\'/api/test3.json\')console.log(url3) //拿到url3返回值} catch (err) {console.log(err)}}const generator = main()const result = generator.next()result.value.then((data) => {const result2 = generator.next(data)if (result2.done) returnresult2.value.then((data) => {const result3 = generator.next(data)if (result3.done) returnresult3.value.then((data) => {generator.next(data)})})}, reason => {generator.throw(new Error(reason))})

上面的代码我们可以写到一个递归函数里面,结束条件是当 reault.done为true的时候结束,对代码进行优化:

const generator = main()const result = generator.next()//封装到getGenerators函数里面,function getGenerators(result){if(!result.done){result.value.then(data=>{getGenerators(generator.next(data))},err=>{generator.throw(new Error(reason))})}}//调用getGenerators(result)

async/await

是es2017新增的一个异步处理方案,它是一个语法糖,用起来很简单

用法如下:

//在函数前面加asyncasync function main() {try {//await代表等待const url = await ajax(\'/api/test.json\')console.log(url) //拿到url返回值const url2 = await ajax(\'/api/test2.json\')console.log(url2) //拿到url2返回值const url3 = await ajax(\'/api/test3.json\')console.log(url3) //拿到url3返回值} catch (err) {console.log(err)}}main()``
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Promise,Generator,async/await学习总结基本用法