当前位置: 首页 > news >正文

生成器的应用 async与await实现

生成器配合使用函数

  • yield 将暂停执行代码,同时把函数返回值传递出去
function s(){console.log('ss');
}
function * f(){/*当 next() 调用时从头开始执行直到yield 开始检查后面的表达式现在是一个函数,那么首先执行函数当函数执行完毕,有返回值下面相当于 yield undefined*/yield s();
}//生成器对象
let g = f();    
//开始执行
console.log(g.next());//{value: undefined, done: false}

生成器配合使用Promise

  • 第一步
  • yield 可以把返回值传递出去,由next()来接受

function do_it(arg){return new Promise((r , j ) =>{setTimeout(() => {r(arg);}, 1000);});
}function * f(){//yield new Promise(...)yield do_it('第一步');
}let g = f();
// res :{value: Promise, done: false}
// res.value 是 yield 传回来的Promise
let res = g.next();
res.value.then(res=>{//第一步console.log(res);
});
  • 第二步
  • next(参数) 可以把参数传递给yield,让yield恢复执行
function do_it(arg){return new Promise((r , j ) =>{setTimeout(() => {r(arg);}, 1000);});
}function * f(){/*yield Promise 并暂停流程*/let res = yield do_it('第一步');//第一次: 第一步console.log('第一次:',res);// yield 第二个 Promise, 同时暂停执行res = yield do_it(res + ' 第二步');}let g = f();
// next 获得 yield 的第一个Promise
let res = g.next();
res.value.then(res=>{/*等第一个Promise执行完后next将第一个Promise的结果传递进去并获得第二个Promise*/let r = g.next(res);   // 第二个Promiser.value.then(res=>{//第一步 第二步console.log(res);});
});
  • 第三步,改良上面的代码
  • 上面代码中都需要自己手写then,再调用next()来执行,其代码结构是一致的
  • 利用递归自动完成

function do_it(arg){return new Promise((r , j ) =>{setTimeout(() => {r(arg);}, 1000);});
}function * f(){let res = yield do_it('第一步');console.log(res);   //第一步res = yield do_it(res + ' 第二步');console.log(res);   //第一步 第二步res = yield do_it(res + ' 第三步');console.log(res);   //第一步 第二步 第三步
}//使用递归来自动化完成
function auto_run(g){function run(arg){let result = g.next(arg);if(result.done)return;result.value.then(res=>{run(res);});}run();
}auto_run(f());

进化到async await

  • 使用async await来简化上面操作
  • 可先看后面的async await的使用

function do_it(arg){return new Promise((r , j ) =>{setTimeout(() => {r(arg);}, 1000);});
}// 异步迭代器 async function *
async function* f(){let res = await do_it('第一步');console.log(res);res = await do_it(res + ' 第二步');console.log(res);res = await do_it(res + ' 第三步');console.log(res);
}(async ()=>{let g = f();let r = await g.next(); //一直迭代到{done:true}时console.log('awwait:',r);
})();

async

  • async 返回一个Promise
async function f(){//return Promise.resolve(123);return 123;
}
let pr = f();
pr.then(res=>{console.log(res);   //123
});
  • 如果函数内部有异常则返回一个Promise.reject();
async function f(){throw new Error('error');
}
let pr = f();
//增加一个 rejected 回调
pr.then(null,res=>{console.log(res);   //error
});

async声明的函数

  • 以下两者等价
async function f(){return 123;
}function ff(){return new Promise((resolve, reject )=>{try{resolve(123);}catch(e){reject(e);}});
}

await

  • await后跟一个表达式,需要在async声明的函数中使用
  • yield的增强版, await将先执行表达式,再暂停流程
  • yield需要手动调用next()执行下一步, await全自动
  • await将创建一个Promise : 使用Promise.resolve()
  • 简单理解就是使用then
async function f(){// await Promise.resolve(3);let res = await 3;console.log(res);  //3
}
f();
  • await 做了什么
async function f(){let result = await 3;
}//相当于
async function f(){Promise.resolve(3).then(res=>{let result = res;});
}
  • 如果await 后面的表达式是一个Promise
//用于返回一个Promise
function test(){return new Promise((resolve , reject)=>{resolve(1);});
}async function f(){let result = await test();
}
  • await相当于
function ff(){//执行此函数,返回一个Promiselet ret = test(); /*await创建一个Promise使用resolve把test()返回值传入*/let await_new_promise = new Promise((resolve,reject)=>{/*resolve的调用时机在: ret 中的 resolve/reject 调用后let res = ret.resolve(1);resolve(res);*/resolve(ret);});// 使用then添加注册函数来获取值await_new_promise.then(res=>{// 相当于 let result = await test();let result = res;console.log(res);   //1});
}

await的yield特性体现在哪里

  • 把上面的代码稍作修改
  • 把await的代码放入一个生成器中,加入yield
  • 外部代码就能使用 .next() 来控制流程
function * gen(){//先调用test(),返回的是一个Promiselet ret = test();//创建一个Promiselet await_new_promise = new Promise((await_resolve, await_reject)=>{//使用Promise.resolve来处理结果await_resolve(ret);});// 传递一个Promiseyield await_new_promise;
}

async await 整体实现

  • 根据上面所知 async 声明的函数将返回一个Promise
  • await将创建一个Promise,并使用then来获取值
  • await是增强版的yield,可暂停流程,也就是使用生成器来控制流程
  • 有如下代码
function test(){return new Promise((resolve , reject)=>{resolve(1);});
}async function f(){let result = await test();
}
  • 异步函数 f 的完整实现
function ff(){// async 声明的函数将返回一个Promisereturn new Promise((r , j)=>{//await 做的事function * gen(){let ret = test();let await_new_promise = new Promise((await_resolve, await_reject)=>{await_resolve(ret);});yield await_new_promise;}// 外部控制流程try {// 第一个 await let g = gen();//next返回一个对象{done:true/false,value:yield后跟的值}let obj = g.next();//获取Promiselet first_await = obj.value;//最终结果let result = undefined;//then中添加fulfilled对应回调来获取结果first_await.then(res=>{result = res;console.log(res); // 1});r(result);} catch (error) {j(error);}
});
}
ff();

与生成器代码比较


function do_it(arg){return new Promise((r , j ) =>{setTimeout(() => {r(arg);}, 1000);});
}// 生成器
function * f(){let res = yield do_it('第一步');console.log(res);   //第一步res = yield do_it(res + ' 第二步');console.log(res);   //第一步 第二步res = yield do_it(res + ' 第三步');console.log(res);   //第一步 第二步 第三步
}
/*生成器需要自己手动调用或者写递归函数来自动调用let g = f();let res = g.next();res.value.then(res=>{g.next(res);....g.next()...});
*///------------------------------------------------/*使用async await全自动
*/
async function ff(){let res = await do_it(1);res = await do_it(res+1);res = await do_it(res+1);console.log('res:',res); // 3
}
ff();

http://www.mrgr.cn/news/96173.html

相关文章:

  • 【leetcode hot 100 347】前 K 个高频元素
  • centos8上实现lvs集群负载均衡nat模式
  • mysql--主从复制--部署
  • 循环神经网络(RNN)
  • 大数据(2)Hadoop架构深度拆解:HDFS与MapReduce企业级实战与高阶调优
  • STM32F103_LL库+寄存器学习笔记08 - DMA串口发送,开启DMA传输完成中断
  • java程序员实用英语学习总结
  • STM32F103_LL库+寄存器学习笔记07 - 串口接收缓冲区非空中断
  • 网络安全法律法规简介
  • 锐捷EWEB路由器 timeout.php任意文件上传漏洞代码审计(DVB-2025-9003)
  • webpack配置详解+项目实战
  • pytorch+maskRcnn框架训练自己的模型以及模型导出ONXX格式供C++部署推理
  • 我的创作纪念日——三周年
  • unity 做一个圆形分比图
  • #C8# UVM中的factory机制 #S8.5# 对factory机制的重载进一步思考
  • 第十四届蓝桥杯省赛电子类单片机学习记录(客观题)
  • UDP视频传输中的丢包和播放花屏处理方法
  • Linux一步部署主DNS服务器
  • RGB-T综述
  • FALL靶场通关攻略