【问题标题】:What is the (potential) drawback of using async functions everywhere?到处使用异步函数的(潜在)缺点是什么?
【发布时间】:2019-06-23 16:27:04
【问题描述】:

我正在学习 Javascript。这听起来像是一个疯狂的想法,但我在 Google 上找不到明确的答案。我可以在任何地方用async function 替换我所有的常规函数​​/方法吗?我的意思是这似乎没有缺点,它让事情变得简单多了。如果情况只涉及同步步骤,您就不要使用await,它会像正常功能一样工作。简单!

就我个人而言,我发现必须区分 async 函数和普通函数是不必要的繁琐。就像开手动挡汽车一样,汽车本身可以很容易地自行处理传动装置。

我错过了什么吗?

【问题讨论】:

    标签: javascript async-await


    【解决方案1】:

    async 函数总是返回 Promises。这意味着,当您处理异步事件时,您必须先将返回的Promise 转换为一个值,然后才能使用它。例如:

    const return4 = async () => 4;
    console.log(4 + return4());

    相反,您将不得不使用(不必要的冗长):

    const return4 = async () => 4;
    (async () => {
      console.log(4 + await return4());
    })();

    (或在使用前拨打return4电话.then

    另一方面,如果 return4 不是 async,当然单独使用 console.log(4 + return4()); 就可以了。

    async 函数的另一个问题是,将它们转换为 ES5 代码(允许与 IE 等过时的浏览器兼容)需要regenerator-runtime,这是非常重量级的。例如,使用 Babel 转译以下单行代码:

    const foo = async () => console.log('async!');
    

    当您将其插入repl 时,您会得到:

    "use strict";
    
    function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
      try {
        var info = gen[key](arg);
        var value = info.value;
      } catch (error) {
        reject(error);
        return;
      }
      if (info.done) {
        resolve(value);
      } else {
        Promise.resolve(value).then(_next, _throw);
      }
    }
    
    function _asyncToGenerator(fn) {
      return function() {
        var self = this,
          args = arguments;
        return new Promise(function(resolve, reject) {
          var gen = fn.apply(self, args);
          function _next(value) {
            asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
          }
          function _throw(err) {
            asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
          }
          _next(undefined);
        });
      };
    }
    
    var foo =
      /*#__PURE__*/
      (function() {
        var _ref = _asyncToGenerator(
          /*#__PURE__*/
          regeneratorRuntime.mark(function _callee() {
            return regeneratorRuntime.wrap(function _callee$(_context) {
              while (1) {
                switch ((_context.prev = _context.next)) {
                  case 0:
                    return _context.abrupt("return", console.log("async!"));
    
                  case 1:
                  case "end":
                    return _context.stop();
                }
              }
            }, _callee);
          })
        );
    
        return function foo() {
          return _ref.apply(this, arguments);
        };
      })();
    
    

    这还取决于 regeneratorRuntime 是否已经包含在脚本中,这是您可以看到 here 的 700 多行代码。

    在功能较弱的系统上,这可能会对性能造成不小的影响。这就是为什么有些人(比如 AirBNB 风格指南)宁愿从不使用 async 函数,即使它们使脚本的异步控制流更加清晰。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-09
      • 2015-03-08
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      • 2018-10-07
      • 2021-08-07
      • 1970-01-01
      相关资源
      最近更新 更多