【问题标题】:How can I use async/await while assigning a variable?如何在分配变量时使用 async/await?
【发布时间】:2019-04-05 14:30:20
【问题描述】:

我有一个基于异步函数结果设置的变量,该变量是initialState

const initialState = await getContacts()
  .then((body) => {
    console.log('body: ');
    console.log(body);
    return body;
  }).catch(err => console.log(err));

我的 getContacts() 返回一个应该是这个函数的结果的承诺:

export async function getContacts() {
  let data = fetch('/api/contacts').then((data) => {
    console.log(data);
    return data.json();
  }).catch(err => console.log(err));

  return data;
}

我认为我的部分问题可能是我试图从一个普通的 javascript 文件中调用它。它实际上是我的 React 应用程序的 index.js。在加载应用程序之前,我正在从数据库中获取我的应用程序的某种初始状态。我应该移动这段代码并对其进行大量清理,但我试图让一个快速而肮脏的测试启动并运行。我收到编译器错误:

SyntaxError: \contacts\client\index.js: Can not use keyword 'await' outside an async function

包含 await 的我的 index.js 是这样的:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import App from './components/app';
import reducers from './reducers';
import { composeWithDevTools } from 'redux-devtools-extension';
import { getContacts } from './server/api';

const initialState = await getContacts()
  .then((body) => {
    console.log('body: ');
    console.log(body);
    return body;
  }).catch(err => console.log(err));

console.log('initial state: ');
console.log(initialState);

const composeEnhancers = composeWithDevTools({});
ReactDOM.render(
  <Provider store={ createStore(reducers, initialState, composeEnhancers(
  )) }>
   <App />
  </Provider>
, document.querySelector('.container'));

【问题讨论】:

  • 您在设置 initialState 时使用了 await,这是错误的。正如错误所暗示的,await 只能在 async 函数中使用。检查下面@doublesharp 的答案。它的合法性。
  • @jtabuloc 是的。但之前的问题是我的后端端点不工作,我的 webpack 开发服务器有问题。
  • @VishalGulati 当我这样做时,我得到一个 Uncaught ReferenceError: regeneratorRuntime is not defined 错误。我认为这是由于在 React 中使用了 async/await?至少这是我上次遇到这个问题时发现的。

标签: javascript reactjs express asynchronous async-await


【解决方案1】:

将对getContacts() 的调用封装在一个异步函数中——您也不想将async/await.then() 混淆,

(async function() {
  const contacts = await getContacts();
  console.log('contacts', contacts);
})();

【讨论】:

    【解决方案2】:

    您的假设是正确的,即尝试使用 await 调用异步 getContacts() 函数是代码问题的一部分。为了调用像await getContacts(){} 这样的函数,您需要将该代码包装在一个异步函数中,该函数的定义如下:

    async function wrapperFunction() {
        const contacts = await getContacts()
        console.log('body: ')
        console.log(contacts)
    }
    

    另外,如果你想执行这个函数并添加一些错误处理逻辑,你可以这样做:

    wrapperFunction().catch((error) => {
        console.log(error)
    })
    

    contacts 变量将成为您的初始状态,并传递给您的 Redux 存储 createStore() 函数调用。

    可以将两者混合使用,因为它们都是处理异步逻辑的语法,但您只需将两者的用法正确组合在一起即可。我建议通读 Mozilla documentation 关于异步函数的内容,以更好地了解如何使用 async/await 以及如何将这个约定与 Promise 语法一起使用。

    【讨论】:

      【解决方案3】:

      如果不在异步函数声明中,则不能使用 await。

      也许这可以工作:

      const initialState = async () => {
        try {
          await getContacts();
        } catch (err) {
          console.log(err)
        }
      }
      console.log('initial state: ');
      console.log(initialState);
      

      您错过了将 async/await 与 .then() 混合的要点

      那时你不需要,因为 await 返回一个已解决的承诺。

      【讨论】:

      • 我现在收到了index.js?1942:32 Uncaught ReferenceError: regeneratorRuntime is not defined。我相信这是由于在 React 中使用了 async/await,我之前尝试过类似的实现,但无法通过 async/await 在 React 中使用它。
      • 这是通过将 initialState 分配给 async 函数来将其设置为 Promise。当你console.log 时,它不会是getContacts() 的结果,而是未解决的承诺。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      相关资源
      最近更新 更多