【问题标题】:Cannot use await on exported function?不能在导出函数上使用等待?
【发布时间】:2019-10-22 06:52:22
【问题描述】:

我有一个围绕 Axios 的 APIService 包装器,我返回它并使用 .then() 来处理承诺,但现在我想使用 async/await;我想知道为什么我的功能在这种新情况下不再起作用;因为我在返回之前只向 Axios 实例添加了几个配置。

转向 async/await 的逻辑是因为这似乎是使用 nextjs 和 getInitialProps 的最佳实践方式。

我的 APIService.js;

import axios from "axios";
import { API_URL } from './constants';

const config = {
  baseURL: API_URL,
};

const APIService = axios.create(config);

APIService.interceptors.request.use(request => {
  const token = 'blah;
  request.headers.Authorization = token ? `Bearer ${token}` : '';
  return request;
});

APIService.interceptors.response.use(
  response => response,
  error => {
    if (error.response.status === 401) {
      // do something
      return true;
    }
    return Promise.reject(error);
  },
);

export default APIService;

我希望上述函数在这样调用时能够工作;

import APIService from '../../utils/APIService';

Page.getInitialProps = async function({ res, query }) {

  const req = await APIService.get('/endpoint', {});

  const { data } = req;

  return {
    data
  };
};

我应该如何重构我的 APIService 以在上述场景中工作,以及为什么需要重构,因为我不操纵 Axios 函数的工作方式...

【问题讨论】:

  • 除非用async 函数封装,否则不能在全球范围内使用
  • 您只能在async 函数内调用await。您必须在 async 函数中调用 const req = await APIService.get('/endpoint', {});。目前,它不能位于模块的顶层。它必须在函数内部。
  • @EslamAbuHugair - 完全准确地说,模块范围的顶层不是全局范围。它是模块范围。问题是(直到我们在模块中获得顶级await)您必须在async 函数内才能使用await,并且模块范围的顶级不在async 函数内。
  • 有人可以使用我的代码作为示例来说明我需要如何重写它吗?它是从异步函数内部调用的。我将更新我的代码。

标签: reactjs axios es6-promise next.js


【解决方案1】:

await 不能在顶层使用,它必须在异步函数内部。有一种常见的做法可以解决此问题,但不建议这样做:

(async function() {
  const response = await APIService.get('/endpoint', {});
  ...
}());

// or

(async function() {
  const response = await APIService.get('/endpoint', {});
  ...
}()).then(...);

有一项建议允许在顶层进行异步导入,但仍处于第 3 阶段。 您可以在this article

中阅读有关此主题的更多信息

【讨论】:

  • 我刚刚澄清了我是如何在异步函数中调用它的。我只是不明白为什么 await axios 有效,而 await APIService 不...所以问题一定是我的 APIService.js
  • @dhj 我做了一个gist,它在我的本地主机上就像一个魅力。我发现了什么: - 如果我从服务器获得响应,它就可以工作。 (/ 端点) - 承诺拒绝,所以如果状态码不是 2XX 或 401,我会得到默认错误页面。(/not-found 端点) - 在 401 的情况下我会收到一个 js 错误,因为我们用 true 解决没有数据键。 (/unauthorized 端点)所以返回 true 可能会破坏您的代码,或者我需要有关该问题的更多信息。 “它不再有效”是什么意思?
  • 你帮我调试了一下,是路径错误;但现在最初的混乱是有道理的——我没有操纵原始的 APIService,所以它可以在 await 或 then 下正常工作——现在一切都很好。所以谢谢@ikarasz
【解决方案2】:

问题是我定义的 API_URL,问题没有在堆栈中冒泡,它就像路径中的双 // 一样简单。

【讨论】:

    【解决方案3】:

    Async 和 Await 是 Promise 的扩展。它们实际上是在 Promise 之上构建的。Await 不能在 Async 函数之外使用。请记住 asunc 和 await 的这些规则。

    1. 您必须仅在使用 async 关键字声明的闭包中使用 await 关键字。
    2. 在异步闭包内部,如果使用 await 关键字调用另一个异步函数,则下一行将不会运行,直到该行的承诺已解决。

      异步函数 myFunc() { 返回 10; }

      myFunc().then(alert); //输出:10

    Async 告诉你一个 Promise 会被返回,如果 Promise 没有被返回,javascript 会自动把它放到 resolve 的部分。运行 myFunc().then() 有效,因为 myFunc 正在返回一个 promise。如果 Async 和 await 对您不起作用,请尝试编写自定义 promise 并查看它是否有效。您可以转到此链接 Promise - JavaScript

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-12
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2019-09-17
      • 2021-06-02
      相关资源
      最近更新 更多