Async/Await 代码案例说明
概要
网上关于async await 的文章挺多的,简单记录一下代码示例 加深理解。
1.先前:回调来处理异步代码(不便于理解与维护)
2.es6:Promise带来了.then() (不能阻塞直到promise完成)
3.Async/Await的增加(让接口按顺序异步获取数据)
代码说明
说明一:
test(){ console.log(this.TextDecoder1())//将打出一个promise对象 this.TextDecoder1().then(res=>{ console.error(res)//6 }) this.TextDecoder2().then(res=>{ console.error(res)//undefined }) }, async TextDecoder1(){ return 6 }, async TextDecoder2(){ },

执行 test() 函数,打出上面的结果!
0.建立在Promise上,并且与所有现有的基于Promise的API兼容
1.自动将常规函数转换成Promise,返回一个 Promise 对象-----(TextDecoder1 函数被转了)
2.如果在async函数中 return 一个直接量,async 会把这个直接量通过Promise.resolve() 封装成 Promise 对象;
如果 async 函数没有返回值,它会返回 Promise.resolve(undefined)-----(TextDecoder1 的返回值 6被 resolve())
说明二:
ddd(){ return new Promise(resolve => { setTimeout(() => resolve('66666'), 5000); }); }, async test(){ let rest = await this.ddd() console.log(rest) console.log('6666')// 等了5秒后执行的 },
await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值,所以,await后面实际可以接收普通函数调用或者直接量!
如果await等到的不是一个promise对象,那跟着的表达式的运算结果就是它等到的东西;
如果是一个promise对象,await会阻塞后面的代码,等promise对象resolve,得到resolve的值作为await表达式的运算结果
场景记录
以下内容 直接搬运吧 就是简单记录!
一:同时发出三个不互相依赖的请求 此时我们需要用Promise.all()将异步调用并行执行
async function dbFuc(db) { let docs = [{}, {}, {}]; let promises = docs.map((doc) => db.post(doc)); let results = await Promise.all(promises); console.log(results); } // 或者使用下面的写法 async function dbFuc(db) { let docs = [{}, {}, {}]; let promises = docs.map((doc) => db.post(doc)); let results = []; for (let promise of promises) { results.push(await promise); } console.log(results); }
二:假设一个业务需要分步完成,每个步骤都是异步的,而且依赖上一步的执行结果,甚至依赖之前每一步的结果,就可以使用Async Await来完成
function takeLongTime(n) { return new Promise(resolve => { setTimeout(() => resolve(n + 200), n); }); } function step1(n) { console.log(`step1 with ${n}`); return takeLongTime(n); } function step2(m, n) { console.log(`step2 with ${m} and ${n}`); return takeLongTime(m + n); } function step3(k, m, n) { console.log(`step3 with ${k}, ${m} and ${n}`); return takeLongTime(k + m + n); } async function doIt() { console.time("doIt"); const time1 = 300; const time2 = await step1(time1); const time3 = await step2(time1, time2); const result = await step3(time1, time2, time3); console.log(`result is ${result}`); console.timeEnd("doIt"); } doIt();
三 自己需求的场景:上面的场景二 步骤有限!
有个导入数据的功能,上万条甚至更多,需要经过服务进行校验并返回详细信息,并且按照excel中数据的顺序!!
此时需要 循环继发执行!!采用 for 循环!(foreach map等都不行 都会并发执行了)(没用async的时候 用的递归处理!!)
//展示导入数据 async importSave(datas) { let elLoad = this.$loading({ target: $(this.$refs.tabQryDiv)[0], text: "数据校验中..." }); let that = this; let errorArr =[];//请求失败的数据 let arr = [];//请求成功的数据 let all = []; for (let i = 0; i < datas.length; i += 1000) { all.push(datas.slice(i, i + 1000)); } let index = 0; // async 部分 // for(let item of all){ // let vipLockUnlockBeanList = []; // item.map(ele=>{ // let da = {"vipId":ele.vipId,"lockReason":ele.lockReason}; // vipLockUnlockBeanList.push(da); // }) // await this.querys(vipLockUnlockBeanList).then(rest=>{ // rest.map(item=>{ // if(item.flag =='N'){ // arr.push(item); // } // if(item.flag =='Y'){ // errorArr.push(item); // } // }) // }); // } // console.log('2222') // this.tableData = arr; // if(errorArr.length !=0){ // this.falseData = errorArr; // this.$refs.dialogResult.alterVisible(); // } // this.$nextTick(function(){ // this.$message.success("数据导入并校验成功"); // elLoad.close(); // this.$refs.importDbTable.reloadLeftData(this.tableColumn,this.tableData); // }) //递归 function querys(){ let vipLockUnlockBeanList = []; all[index].map(item=>{ let da = {"vipId":item.vipId,"lockReason":item.lockReason}; vipLockUnlockBeanList.push(da); }) let params ={ "pageNum": 0, "pageSize": 0, "sortColumn":"", "sortDirect":"", "vipLockUnlockBeanList":vipLockUnlockBeanList } lockUnlockSaveQuery(params).then(res=>{ let rest = res.vipLockUnlockShowBeanList; if(res.success){ rest.map(item=>{ if(item.flag =='N'){ arr.push(item); } if(item.flag =='Y'){ errorArr.push(item); } }) } index++; if(index<all.length){ querys(); }else{ that.tableData = arr; if(errorArr.length !=0){ that.falseData = errorArr; that.$refs.dialogResult.alterVisible(); } that.$nextTick(function(){ that.$message.success("数据导入并校验成功"); elLoad.close(); that.$refs.importDbTable.reloadLeftData(that.tableColumn,that.tableData); }) } }) } querys(); },
使用小贴士
由于await后面的promise运行结果可能是rejected,最好把await放入try{}catch{}中
async function r(){ try{ let content1 = await read('1.txt','utf8'); let content2 = await read(content1,'utf8'); return content2; }catch(e){ console.log('err',e) } } r().then(function(data){ console.log('data',data); },function(err){ console.log('err1',err); })
666

浙公网安备 33010602011771号