为了账号安全,请及时绑定邮箱和手机立即绑定

使用es6的generator函数处理异步请求

标签:
React.JS React

什么是Generator

Generator和Promise一样也是es6提供的一种异步编程的解决方案。

promise通过把执行过程代码和结果处理的代码解藕来加强代码的可读性,Generator就是直接让我们使用同步的语法来完成异步处理。为啥要这么做呢,因为人类更能理解同步的思维。

那么Generator是怎么做到的呢?因为Generator 函数可以暂停执行和恢复执行

首先,我们看看最基本的Generator函数是什么样的?

function * gen() {

    console.log('执行');

}

gen();


看起来就是在function关键字和函数名之间加了一个*号,那么generator函数是怎么执行的呢?

它和普通的函数执行方式是一样的,也是使用函数名加一对括号进行调用,不同的地方在于当我们执行generator函数时,generator函数体并没有执行,而且会返回一个迭代器对象

可以声明一个变量let g接收gen()返回的值

let g = gen();

当我们调用g.next()函数的时候,generator函数才会执行。

刚刚讲过generator函数是可以暂停执行和恢复执行的,在generator函数内可以使用yield语句,当遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

function * gen() {

    yield 1;

}

let g = gen(); // 返回一个迭代器对象



当执行next函数的时候,

console.log(g.next()); // { value: 1, done: false }

会返回一个对象{value: "a", done: false},'a'就是g函数执行到第一个yield语句之后得到的值,false表示generator函数还没有执行完,只是在这暂停

如果再写一行gen.next();呢?

返回{value: undefined, done: true} done为true,代表generator函数执行完了。


另外generator函数也是可以使用return语句的,

function * gen() {

    yield 1;

    return 2;

}

let g = gen(); // 返回一个迭代器对象

console.log(g.next()); // { value: 1, done: false }

console.log(g.next()); // { value: 2, done: true }

执行第二个next函数时,会返回一个对象,value属性为return语句返回的值,done为true,代表函数执行完毕

如果继续执行next函数呢,也不会报错,会返回{ value: undefined, done: true }

实际上next函数还可以接受参数,这个参数就是是上一个yield语句返回的值,注意,是上一个yield语句返回的值哦。

function * gen() {

    let a = yield 1;

    console.log(a);

    yield a;

}

let g = gen(); // 返回一个迭代器对象

console.log(g.next()); // { value: 1, done: false }

console.log(g.next(10)); // { value: 2, done: true }

如果给第一个next函数传参,什么都不会发生,因为这个参数是作为上一个yield语句的返回值的,既然是第一个next函数,说明上面没有yield语句了,传的参数也没有变量接收

刚刚开始的时候,讲过generator函数是用于解决异步编程的,那么最后,我们使用generator函数写一个函数,用于处理异步请求,使用generator函数可以让我们按照同步的语法来完成异步处理

// ajax函数将返回Promise对象:

function mockAjax(method, url, data) {

    return new Promise(function (resolve) {

    setTimeout(() => {

        const result = {status: 100, msg: 'success', data}

        resolve(result)

    },1000);

    });

}

function *gen() {

    let role = yield mockAjax('GET', '/role?userId=' + 1, {id: 1});

      console.log('role', role);  

      let product = yield mockAjax('GET', '/product?roleId=' + role.id, [{title: '衣服'}]);

      console.log('product', product);  

}

function run(g) {

    let it = g(), ret;

  (function iterate(val) {

      ret = it.next(val);

    if(!ret.done) {

        // 简单测试返回值是否是一个promise

            if (ret.value instanceof Promise) {

                // 等待promise返回

                ret.value.then(iterate);

            }

    }

  })();

}

run(gen);

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
104
获赞与收藏
33

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消