为什么异步act()调用不需要返回值

问题描述 投票:1回答:2

我不知道下面的await调用实际上是怎么做的,因为它不等待回调中的任何东西。它只是立即返回。没有它是行不通的,所以我知道这是必要的,但是实际上阻止了它是什么呢?即使没有await关键字,它通常也不会等待(用于排队的事件和剩余状态更新)吗?回调内部没有异步的等待如何产生影响?

当我最初寻找解决方案时,我已经看到许多使用这种模式的示例。这就是我到达这里的方式。

import React from "react";
import {
  View,
  TextInput,
  Button
} from "react-native";
import { Formik } from "formik";
import partial from "lodash/fp/partial";

const Form = ({ task = {}, onSubmit }) => (
  <Formik initialValues={task} onSubmit={onSubmit}>
    {({ setFieldValue, handleSubmit, values }) => (
      <View>
        <TextInput
          onChangeText={partial(setFieldValue, ["task"])}
          value={values.task}
        />
        <Button onPress={handleSubmit} title="Submit" />
      </View>
    )}
  </Formik>
);

describe("...", () => {
   it("...", async () => {
       const handleSubmit = jest.fn();

       let root;

       act(() => {
           root = create(<Form onSubmit={handleSubmit} />);
       });

       // __HERE__
       await act(async () => {
           // Nothing is being returned here nor is it waiting on anything with an await call
           root.root.findByType(Button).props.onPress();
       });

       expect(handleSubmit).toHaveBeenCalled();
   })
}) 
reactjs jest formik
2个回答
0
投票

您需要知道的第一件事是“ async是做什么的?”

这里是一个例子。

let a = () => 'hey'
let b = async () => 'hey'

// string
console.log(a())

// Promise object
console.log(b())

[在函数中添加async时,会将函数“包装”在promise周围。

因此您可以在代码中全部添加async,它将起作用,唯一的区别是它将返回Promise对象,而不是从函数返回的结果。

您说过

没有它不起作用

但是您没有解释发生错误的原因或原因。请对此更加清楚。

但是据我的猜测,act需要接受承诺而不是正常功能。也许这就是为什么您需要使用async的原因,否则就无法使用。


0
投票

Dislcaimer:不太熟悉您使用的框架,但这是我认为正在发生的事情。

没有返回值的async函数,实际上在没有await的情况下会返回一个值。它返回一个Promise,解析时不提供任何值,但解析时仍然很重要。如果确实使用await,则它将按预期返回undefined

我猜您的代码正在此处异步呈现您的应用。当您运行代码来按下按钮时,我相信Button也是async。这意味着您的按钮按下将运行,并更改状态,从而安排重新渲染,该渲染将在几毫秒后的下一个事件循环中发生。

而且我认为act()已挂接到React渲染中,因此将异步函数传递给act()将导致它仅在下一次渲染发生后才解析。


简而言之,这段代码简单地说,在下一个异步渲染之后恢复执行。

await act(async => { /*...*/ })

但是此代码没有await,实际上不会停止执行,并且您的测试将在下一次渲染实际发生之前继续进行。测试执行完成后,诺言将解决。

act(async => { /*...*/ })

而且此代码根本不希望任何异步操作,就像前面的示例一样,它将立即立即继续。

act({ /*...*/ })
© www.soinside.com 2019 - 2024. All rights reserved.