IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    看看编译后async/await

    i5ting发表于 2016-06-11 07:34:58
    love 0

    我也来凑个热闹,看看编译后async/await

    在koa 2里使用async

    'use strict';
    
    var http = require('http');
    var koa = require('koa');
    var app = new koa();
    
    
    // number of middleware
    
    var n = parseInt(process.env.MW || '1', 10);
    console.log('  %s async middleware', n);
    
    while (n--) {
      app.use(async (ctx, next) => {
        await next();
      });
    }
    
    var body = new Buffer('Hello World');
    
    app.use(async (ctx, next) => {
      await next();
      ctx.body = body;
    });
    
    
    // var apprequire('./koa2-async.js')
    app.listen(3333);
    
    module.exports = app
    
    

    使用babel编译后,如下

    'use strict';
    
    function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
    
    var http = require('http');
    var koa = require('koa');
    var app = new koa();
    
    // number of middleware
    
    var n = parseInt(process.env.MW || '1', 10);
    console.log('  %s async middleware', n);
    
    while (n--) {
      app.use((() => {
        var ref = _asyncToGenerator(function* (ctx, next) {
          yield next();
        });
    
        return function (_x, _x2) {
          return ref.apply(this, arguments);
        };
      })());
    }
    
    var body = new Buffer('Hello World');
    
    app.use((() => {
      var ref = _asyncToGenerator(function* (ctx, next) {
        yield next();
        ctx.body = body;
      });
    
      return function (_x3, _x4) {
        return ref.apply(this, arguments);
      };
    })());
    
    // var apprequire('./koa2-async.js')
    app.listen(3333);
    
    module.exports = app;
    

    看一下_asyncToGenerator函数,格式化后

    function _asyncToGenerator(fn) {
        return function() {
            var gen = fn.apply(this, arguments);
            return new Promise(function(resolve, reject) {
                function step(key, arg) {
                    try {
                        var info = gen[key](arg);
                        var value = info.value;
                    } catch(error) {
                        reject(error);
                        return;
                    }
                    if (info.done) {
                        resolve(value);
                    } else {
                        return Promise.resolve(value).then(function(value) {
                            return step("next", value);
                        },
                        function(err) {
                            return step("throw", err);
                        });
                    }
                }
                return step("next");
            });
        };
    }
    

    很明显,把async函数通过高阶函数转为promise里嵌入的generator来执行的。

    整体来说,随着中间件越多,它的性能越差,可以参见 koa、koa2、koa2-async和express的压测性能比较

    再看await

    app.use(async (ctx, next) => {
      await next();
      ctx.body = body;
    });
    

    翻译后

    app.use((() => {
      var ref = _asyncToGenerator(function* (ctx, next) {
        yield next();
        ctx.body = body;
      });
    
      return function (_x3, _x4) {
        return ref.apply(this, arguments);
      };
    })());
    

    很明显,await只是yield的别名

    结论

    • async/await不需要generator,自己带执行器
    • 翻译后的await = yield

    目前Thunk和Promise是一样,都可以接到yield后面,但await的native里的具体实现里还不好说。

    另外据mikeal说,10月份可能会有async/await的native实现,拭目以待吧

    如有不对的地方,请指正



沪ICP备19023445号-2号
友情链接