简体   繁体   中英

How can I extract data from this returned object in an async function?

I'm trying to do some work in JavaScript - I call an async function from an async function, as shown below.

  useEffect(() => {
    (async () => {
      await asyncFunction();
      // do stuff
    })();
  }, []);

asyncFunction looks like this

const asyncFunction = (dispatch) => {
  return async (data) => {
    try {
      const response = await APICall();

      dispatch({ type: "search", payload: response.data });
    }
    // error handling
}

asyncFunction dispatches to a reducer, which returns return { errorMessage: "", data: action.payload };

With my own testing, I've seen that console.log(asyncFunction()) returns a promise, and console.log(await asyncFunction()) returns nothing.

One weird thing I have noticed is when placing console.log statements in each part of the program, the promise from the function call (in the useEffect block) is printed out first, then the data in the reducer from the console.log statement I added right about return { errorMessage: "", data: action.payload }; .

So my question is, how do I access this data? I've looked at some other threads on here which recommend using .then , but that was unsuccessful. Is there a way to do it without passing in a callback function (doing so would mean I need to restructure the whole program).

This post is a bit long, so if you have any questions, or need additional parts of my program, please let me know.

You can do the same process without returning the function and directly completing the process in it.

Change the use effect code as follows:

useEffect(() => {
    (async () => {
      await asyncFunction(dispatch);
      // do stuff
    })();
  }, []);
const asyncFunction = async (dispatch, data) => {
    try {
      const response = await APICall();
      dispatch({ type: "search", payload: response.data });
    }
    // error handling
}

Because in the function you mentioned you are dispatching data to reducer and not returning the data. So instead you can just do the processing work there.

In case you want to return some data, you can refer the code below:

Previous Code:

const asyncFunction = (dispatch, data) => {
  return new Promise((resolve, reject) => {
    APICall()
      .then((reponse)=>{
        dispatch({ type: "search", payload: response.data });
        //This will return value to the calling function. This will act as a return statement
        resolve(response);
      })
      .catch((err)=>{
        //This will be executed if there is any error.
        reject(err)
      })
  })

Changed Code (as @Bergi said to avoid Promise constructor anti-pattern):

useEffect(() => {
    let mounted = true;
    APICall()
        .then((response) => {
            if (mounted) {
                dispatch({ type: "search", payload: response.data });
                //do some stuff here
            }
        })
        .catch((err) => {
            //handle error here
        })
    return () => mounted = false;
}, []);

Promises would be the best way to return data from async function.

I could be totally wrong, but I think that you might be running into issues returning the async function, explained here in docs .

Also, it looks like you might be calling asyncFunction (inside your useEffect hook) without a value for dispatch? Here:

  (async () => {
      await asyncFunction();
      // do stuff

I regurgitated a custom hook for API calls following your plan: link to sandbox . Hopefully it can be helpful!

AsyncFunction is returning a function, not the data that comes from the API call. What you can do, if I understand your problem correctly, is return the response from the call and remove the initial return statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM