【ES6】Generator+Promise异步编程
一、概念
首先我们要理解Generator和Promise的概念。
Generator:意思是生成器,可以在函数内部通过yeild来控制语句的执行或暂停状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | *Foo(){ yeild console.log( 'step1' ); yeild console.log( 'step2' ); } run(foo){ var step = foo(); while (!step.done){ step.next(); } } run(Foo); // step1 // step2 |
通过上面这个例子可以看到,使用*将Foo声明为Generator函数,然后再执行Foo的时候,不会执行到底,而是执行到第一句yeild就停下来。只有调用next()才会执行到下一步yeild。
Promise:是ES6新增的一个对象,相当于一个容器,是用来专门处理异步处理的。
function request = new Promise((resolve,reject) => { $.ajax({ type: "GET", url: "/someajaxurl", contentType: "application/json", dataType: "json", success: function (data) { resolve(data); }, error: function (xhr) { reject(xhr); } }); }).then(data=>{ // success method }).catch(xhr=>{ // error method });
二、Generator和Promise的结合
假设我们有个需求,需要调用两个接口,并且这两个接口不能同时启动异步调用,而是要先调接口1,在调接口2。
那么在没有使用Generator的情况下是这么写的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // 使用promise异步调用数据 request(url){ return new Promise((resolve,reject) => { $.ajax({ type: "GET" , url: "/someajaxurl" , contentType: "application/json" , dataType: "json" , success: function (data) { resolve(data); }, error: function (xhr) { reject(xhr); } }); }); } // 先调用接口1,再点用接口2 gen(){ var nameList = []; request( 'user/name1' ).then(data => { nameList.push(data) ; request( 'user/name2' ).then(data => { nameList.push(data) }); }); } gen(); |
以上例子会发现最终会有一个长嵌套的回调函数。
如果我们使用Generator的话,那么代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // 使用promise异步调用数据 request(url){ return new Promise((resolve,reject) => { $.ajax({ type: "GET" , url: "/someajaxurl" , contentType: "application/json" , dataType: "json" , success: function (data) { resolve(data); }, error: function (xhr) { reject(xhr); } }); }); } // 使用generator,将回调函数嵌套的写法改为同步写法 *gen(){ var nameList = []; yeild request( 'user/name1' ).then(data => { nameList.push(data) }); yeild request( 'user/name2' ).then(data => { nameList.push(data) }); } // 执行generator的next方式 ( function (){ var step = gen(); while (!step.done){ step.next(); } }); |
使用generator的写法,会发现省去一大堆的嵌套,代码变得直观很多。
三、Async
上面的例子,发现代码变得直观了,但是还需要另外写个方法去执行generator。这时候ES6中的新特性Async,还可以对代码做进一步的优化。
1 2 3 4 5 6 | // 使用async,效果和generator差不多,只不过将函数内部的yeild改为await.但是async自带执行器,不需要另外再写个方法去执行next. async gen(){ var nameList = []; await request( 'user/name1' ).then(data => { nameList.push(data) }); await request( 'user/name2' ).then(data => { nameList.push(data) }); } |
分类:
JavaScript
, ES6
标签:
JavaScript
, ES6
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?