在对await表达式求值后,由await设置的变量未定义

时间:2018-08-03 19:19:11

标签: javascript async-await

我有一些使用async / await的代码给了我一个非常奇怪的问题:我用await语句设置的变量在表达式后抛出未定义的引用rrror!这是代码:

export const fetchPrices = async ({ commit }, ticker) => {
  const key= "*********";
  const url =
    `http://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=${ticker}&interval=1min&apikey=${key}`

  commit(FETCH_PRICES_REQUEST, { ticker })

  try {
    let response = await fetch(url);
    let priceData = await response.json();
  }
  catch (e) {
    console.error(e);
  }

  commit(FETCH_PRICES_SUCCESS, priceData)
};

运行此命令时,函数的最后一行会引发一些错误:

  

ReferenceError:响应未定义

  

未捕获(承诺)ReferenceError:未定义priceData

这对我来说并没有太大意义,因为我的理解是,wait的全部用法是应该在下一行代码中完成对变量的赋值。

我实际上已经解决了这个问题,这与声明变量的位置有关。当我通过将以下行放在函数顶部将声明移到try / catch块之外时,它起作用了:

let response, priceData;

好奇的是,我看着Babel中转换后的代码。声明位于文件顶部,看起来像这样:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

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 fetchPrices = exports.fetchPrices = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(_ref2, ticker) {
    var commit = _ref2.commit;
    var response, priceData, key, url;
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            response = void 0, priceData = void 0;
            key = "EH6GPZQ5X8EUM3MC";
            url = "http://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + ticker + "&interval=1min&apikey=" + key;


            commit(FETCH_PRICES_REQUEST, { ticker: ticker });

            _context.prev = 4;
            _context.next = 7;
            return fetch(url);

          case 7:
            response = _context.sent;
            _context.next = 10;
            return response.json();

          case 10:
            priceData = _context.sent;
            _context.next = 16;
            break;

          case 13:
            _context.prev = 13;
            _context.t0 = _context["catch"](4);

            console.error(_context.t0);

          case 16:

            commit(FETCH_PRICES_SUCCESS, priceData);

          case 17:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, undefined, [[4, 13]]);
  }));

  return function fetchPrices(_x, _x2) {
    return _ref.apply(this, arguments);
  };
}();

关键区别在于第一种情况(case 0)顶部的行:

response = void 0, priceData = void 0;

似乎发生的事情是,如果您没有在函数顶部声明变量,那么情况7和10在尝试分配给这些变量时会失败。

我的问题是这是否是异步/等待编译代码的问题,还是我尝试在try / catch块中声明变量的尝试根本上是错误的。

1 个答案:

答案 0 :(得分:0)

这里的解决方案-如@Mark Meyer和@sesamechicken所指出-是范围界定错误。 let是块作用域的,因此priceData在try {}块之外是未定义的。解决方案是在try块之外定义这些变量。使用var也可能有效。