Javascript wait表达式求值后,wait设置的变量未定义
我有一些使用async/await的代码,这给了我一个非常奇怪的问题:我用await语句设置的变量在表达式后抛出一个未定义的引用rrror!代码如下:Javascript wait表达式求值后,wait设置的变量未定义,javascript,async-await,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&
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:未定义响应
及
未捕获(承诺中)引用错误:未定义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);
};
}();
关键区别在于第一个案例顶部的一行(案例0
):
如果不在函数顶部声明变量,那么案例7和10在尝试分配这些变量时失败
我的问题是,这是否是异步/等待编译代码的问题,或者我在try/catch块中声明变量的尝试是否根本错误 这里的解决方案——如@Mark Meyer和@sesamechick所示——是一个范围错误。Let是块作用域,因此在try{}块之外未定义
priceData
。解决方案是在try块之外定义这些变量。使用var
也可能有效。let
是块范围的。当您在try{}
中声明这些变量时,它们的作用域是由大括号创建的块。使用let/const定义的变量被阻止scope@Akrion响应是,但在try/catch之外,op尝试使用priceData
,其范围仍然是try
。此场景是将这些请求添加到数组并使用promise的完美示例。所有都要解析并运行'commit(FETCH\u PRICES\u SUCCESS,priceData)`函数,imo.@MarkMeyer,我更改了变量名称几次,忘记了更新我在问题中输入的注释。我现在就更新。@fraxture,这个问题确实是一个范围问题,但是承诺。当您可能有多个连续等待时,所有的都会减轻痛苦。
response = void 0, priceData = void 0;