在各处使用异步函数的(潜在)缺点是什么?

时间:2018-07-15 09:22:03

标签: javascript async-await

我正在学习Javascript。这听起来像是个疯狂的主意,但我在Google上找不到明确的答案。我可以随处都可以用async function替换所有常规函数/方法吗?我的意思是,这似乎没有任何缺点,它使事情变得如此简单。在情况仅涉及同步步骤的情况下,您无需使用await,它将像正常功能一样工作。容易!

我个人认为必须区分async函数和正常函数是不必要的负担。就像驾驶手动变速箱汽车一样,汽车本身可以轻松地自行处理齿轮传动。

我在这里想念东西吗?

1 个答案:

答案 0 :(得分:5)

async函数始终返回Promises。这意味着,只要您处理异步内容,就必须先将返回的Promise转换为值,然后才能使用它。例如:

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

相反,您将不得不使用(不必要的罗y):

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

(或在使用前在.then上调用return4

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

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

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

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

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) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

var foo = 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, undefined);
  }));

  return function foo() {
    return _ref.apply(this, arguments);
  };
}();

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

在功能较弱的系统上,这可能会对性能造成不小的影响。这就是为什么有些人(例如,使用AirBNB样式指南的人)更喜欢不使用async函数的原因,即使它们使脚本的异步控制流程更加清晰。