Javascript wait表达式求值后,wait设置的变量未定义

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&

我有一些使用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:未定义响应

未捕获(承诺中)引用错误:未定义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;