ES6-Generator函数和async函数

ES6-异步函数

Generator是一个状态机,它封装了多个内部状态。执行它将生成一个遍历器对象。

Generator有2个特征:

  • 声明时使用function*

  • 函数内部使用yield声明内部状态

    调用函数后,函数并不执行,而且返回的也不是函数运行结果,而是一个指向内部状态的对象。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

yield相当于暂停执行标识,next()相当于恢复执行标识,每调用一次next(),Generator函数才执行一次,直到遇到下一个yield或者return,当遇到yieldruturn时,会在此暂停,并将其代表的值作为value返回。done是遍历标识符,表示是否完成遍历。

yield表达式

  • yield表达式只能用在Generator函数中
  • yield表达式如果用在另一个表达式之中,必须放在园括号中
  • yield表达式用作函数参数或放在赋值表达式的右边可以不加括号
  • yield* 表达式用来在一个Generator函数执行另一个Generator函数
function* foo(a,b){
  yield a;
  yield b;
  return a+b;
}

function* demo() {
  console.log('Hello' + yield); // SyntaxError
  console.log('Hello' + yield 123); // SyntaxError

  console.log('Hello' + (yield)); // OK
  console.log('Hello' + (yield 123)); // OK

  foo(yield 'a',yield 'b')//OK
  let input = yield;
}

next方法

yield表达式本身没有返回值,next方法可以带一个参数,该参数就被当作了yield表达式的对应变量。

function* foo(x) {
  var y = 2 * (yield (x + 1));
  var z = yield (y / 3);
  return (x + y + z);
}

var a = foo(5);
a.next() // Object{value:6, done:false},第一次会将传入的参数赋值给x
a.next() // Object{value:NaN, done:false},由于yield并没有返回值,所以y为undefined
a.next() // Object{value:NaN, done:true}

var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }

Generator返回的并不是一个对象,而是一个指针对象,调用next方法会将指针指向下一个阶段。每一个yield都表示一个阶段,跟下一个阶段并不影响。

Generator.prototype.return()

Generator函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}

var g = gen();

g.next()        // { value: 1, done: false }
g.return('foo') // { value: "foo", done: true }
g.next()        // { value: undefined, done: true }

Generator并不能自动执行,所以它需要一个自动执行器,常用的就是co函数库

async

async函数是Generator函数的语法糖

区别如下:

  • *替换为了asyncasync提到了function的前面,表示函数中有异步操作
  • yield替换为了await,表示紧跟后面的表达式需要等待结果
  • async函数自带了执行器,不需要像Generator一样需要next方法才能执行
  • yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)
  • async返回的是一个Promise对象,Generator函数返回的是一个遍历器对象
var fs = require('fs');

var readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) reject(error);
      resolve(data);
    });
  });
};

var gen = function* () {
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

//async写法
var asyncReadFile = async function () {
  var f1 = await readFile('/etc/fstab');
  var f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

async返回一个promise对象,所以return返回的值将作为then方法的参数。

async函数必须等内部所有的await命令后面的Promise对象执行完成才会执行then方法指定的回调函数。

await

await返回一个Promise对象,如果不是,会被转换成一个立即执行的Promise对象,await将等待当前行执行完成才会继续之后的内容

async function f() {
  await Promise.reject('出错了')
    .catch(e => console.log(e));
  return await Promise.resolve('hello world');
}

f().then(v => console.log(v))
// 出错了
// hello world
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: @babel/plugin-transform-async-to-generator是一个Babel插件,它将async/await语法转换为ES5代码,以便在不支持该语法的环境中运行。要配置该插件,请按照以下步骤操作: 1. 安装@babel/plugin-transform-async-to-generator插件: ``` npm install --save-dev @babel/plugin-transform-async-to-generator ``` 2. 在babel配置文件中添加该插件: ```javascript { "plugins": ["@babel/plugin-transform-async-to-generator"] } ``` 3. 如果您使用的是babel 7及以上版本,可以将插件配置为使用"options"选项: ```javascript { "plugins": [ ["@babel/plugin-transform-async-to-generator", { "module": "bluebird", "method": "coroutine" }] ] } ``` 这里的例子展示了如何使用bluebird库中的coroutine方法来提供async/await功能。您可以使用其他库或方法来实现相同的效果。 注意:如果您使用的是babel 6.x版本,则需要在插件名称前添加"babel-"前缀,例如"babel-plugin-transform-async-to-generator"。 ### 回答2: @babel/plugin-transform-async-to-generator是一个Babel插件,用于将ES7中的`async/await`转换为ES6中的生成器函数。要配置该插件,您需要按照以下步骤进行操作: 1. 首先,安装插件,通过运行以下命令:`npm install --save-dev @babel/plugin-transform-async-to-generator`。 2. 在项目的根目录下创建一个名为`.babelrc`的文件(如果它不存在)。这是Babel的配置文件。 3. 在`.babelrc`文件中,添加以下内容: ```json { "plugins": ["@babel/plugin-transform-async-to-generator"] } ``` 这指示Babel加载并使用@babel/plugin-transform-async-to-generator插件。 4. 如果您使用的是Babel 7以上的版本,可以在`.babelrc`中指定插件的参数。例如,要指定`regenerator`作为插件的参数(用于支持较旧的浏览器),您的`.babelrc`文件应如下所示: ```json { "plugins": [ ["@babel/plugin-transform-async-to-generator", { "regenerator": true }] ] } ``` 这样配置后,Babel将在转换代码时使用@babel/plugin-transform-async-to-generator插件,并根据需要设置生成器函数的参数。 请注意,配置文件`.babelrc`的路径可以根据您的项目结构和工具链的不同而有所不同。记得根据您的实际情况,根据需要设置正确的路径。 希望这能帮到您!如果您有其他问题,请随时提问。 ### 回答3: @babel/plugin-transform-async-to-generator是一个可以将async/await语法转换成generator函数的Babel插件。要配置该插件,你需要按照以下步骤进行操作: 第一步,安装插件: ``` npm install --save-dev @babel/plugin-transform-async-to-generator ``` 第二步,在你的babel配置文件(如.babelrc)中添加插件的相关配置: ```json { "plugins": ["@babel/plugin-transform-async-to-generator"] } ``` 或者,如果你使用的是babel.config.js,可以按照以下方式进行配置: ```javascript module.exports = { plugins: ['@babel/plugin-transform-async-to-generator'] } ``` 完成以上配置后,插件会自动转换你的async/await语法成generator函数,使之能够在不支持async/await的环境中运行。 注意,插件的配置选项是可选的,你可以根据需要进行进一步配置。你可以在插件配置中指定一个"module"选项,该选项用于控制生成的模块类型,可选的值为"commonjs"和"amd"。默认值为"commonjs"。 希望以上回答能够帮助到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值