js异步编程三、生成器函数、Gennerator、Async/Await语法糖

生成器函数就是在普通函数上多了上*号,当调用这个生成器函数的时候不会立即执行函数,而且得到一个生成器对象,直接手动的调用这个生成器的next方法,这个函数的函数体才会开始执行。
在函数的内容可以使用yield的关键词向外返回一个值,在next方法调用的时候可以拿到这个值,在返回的对象中还有个done属性,用来表示这个生成器是否已经全部执行完,而且yield关键词并不会像return一样立即结束函数,只是暂停这个生成器函数,直到下一次调用next方法会继续从yield位置向下执行。
如果给next传参数,会做成yield语句的返回值.

function* foo() {
  console.log("start");

  const res = yield "foo";
  console.log(res);
}

const generator = foo();
const result = generator.next();
console.log(result);

在这里插入图片描述
如果说在外部调用的是生成器throw方法,那这个方法就可以对生成器函数内部抛出一个异常.

function* foo() {
  console.log("start");
  try {
    const res = yield "foo";
    console.log(res);
  } catch (e) {
    console.log(e);
  }
}

const generator = foo();
const result = generator.next();
console.log(result);

generator.throw(new Error("Generator error"));

在这里插入图片描述
Gennerator异步方案(生成器函数):

function ajax(url) {...}
function* main() {
  const user = yield ajax(user.json);
  console.log(users);
}

const g = main();
const result = g.next();

result.value.then(data => {
  g.next(data);
});

用这种方法彻底的消灭了promise的回调,有了近乎于同步代码的体验。多个接口时可以在main中做多个yield的操作。在外部第二次调用的结果也是一个promise对象,一样的接收到value再调用里面的then方法。

function ajax(url) {...}
function* main() {
  const user = yield ajax(user.json);
  console.log(users);

  const posts = yield ajax(posts.json);
  console.log(posts);
}

const g = main();
const result = g.next();

result.value.then(data => {
  const result2 = g.next(data);
  result2.value.then(data => {
    g.next(data);
  });
});

直到返回的done属性为true,说明main方法里执行完,可以用递归的方式,直接done为true结束函数.可以把这个封装成公共的函数。

function ajax(url) {...}
function* main() {
  const user = yield ajax(user.json);
  console.log(users);

  const posts = yield ajax(posts.json);
  console.log(posts);
}

function co(gennerator) {
  const g = generator();
  function handleResult(result) {
    if (result.done) return; //生成器函数结束
    result.value.then(
      data => {
        handleResult(g.next(data));
      },
      error => {
        g.throw(error);
      }
    );
  }
  handleResult(g.next());
}

co(main);

像这样的生成器函数执行器在社区中就有一个更完善的co库

也可以直接使用Async/Await语法糖(语言层面的异步编程标准)

async function main() {
  try {
    const user = await ajax(user.json);
    console.log(users);

    const posts = await ajax(posts.json);
    console.log(posts);
  } catch (e) {
    console.log(e);
  }
}

async最大的好处是不需要配合类似于co这样的执行器,因为这是标准语言层面的异步编程语法,其次async函数会返回一个promise对象,更加利于对整体代码的控制。注意await关键词只能出现在async内部

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值