我有一些使用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块中声明变量的尝试根本上是错误的。
答案 0 :(得分:0)
这里的解决方案-如@Mark Meyer和@sesamechicken所指出-是范围界定错误。 let是块作用域的,因此priceData
在try {}块之外是未定义的。解决方案是在try块之外定义这些变量。使用var
也可能有效。