【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) });
}

  

 

posted @   のんきネコ  阅读(403)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示