How to get normal json object from Promise Object

2019-07-28 23:17发布

问题:

This question already has an answer here:

  • Handling async request with React, Redux and Axios? 4 answers

How to get normal JSON object from Promise Object in react-redux?

My action.js contains:

  export function allEmp() {
      let url = "employees?access_token=";
      let result = ApiCall.getApiCall(url)
      .then(function (response) {
         return response;
       })
       .catch(function (error) {
         return error;
       });
       console.log("result",result);
       return {
         type: "ALL_EMP",
         payload: new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(result);
                }, 2000);
            })
       };
     }

my API call configuration is:

getApiCall(url) {
    let base_url = "http://192.168.1.151:3000/api/";
    let api_token = "1f7169e92c1d0722db575b877707cf0b88b8f0ad";
    let fetch_url = base_url + url + api_token;
    let myHeaders = new Headers({
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    });
    return fetch(fetch_url, {
      method: "GET",
      headers: myHeaders
    })
    .then(function(response) {
      if (response.ok) {
        return response.json();
      } else {
        var error = new Error(response.statusText);
        error.response = response;
        throw error;
      }
    })
    .then(function(json) {
      return json;
     })
  }

My store.js :

import {createStore, combineReducers, applyMiddleware} from "redux";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";

import userDetails from "./reducers/User_reducer";

export default createStore(
    combineReducers({
        userDetails
    }),
    {},
    applyMiddleware(thunk, promise())
);

But here I'm getting Promise object as a result. So that when I'm assigning in payload it is getting as undefined. How should I manipulate it when I'm sending the response as payload.

Can anyone give me some suggestion?

回答1:

react-redux does not support asynchronous action creators out-of-the-box, so you'll need to add a dependency to your project.

Take a look at the redux-thunk middleware, which adds support for asynchronous action creators.

The idea with redux-thunk is that your action creator will trigger another action once the asynchronous code resolves.

In your case, you would have an allEmp action creator that calls another action receiveAllEmp once the Promise resolves:

allEmp Action Creator (using redux-thunk)

export function allEmp() {

    return (dispatch) => {

        return ApiCall.getApiCall(url).then((response) => {

            // Dispatch the receiveAllEmp action

            dispatch(receiveAllEmp(response));

            return response;
        });
    };
}

receiveAllEmp Action Creator (normal action creator)

export function receiveAllEmp(response) {
    return {
        type: "ALL_EMP",
        payload: response,
    };
}


回答2:

Promises represent asynchronous processes whose may not be available immediately. They provide a way to trigger a handler when the result is ready (so your Javascript can go on and get other work done).

To access their result, you place a handler in a .then method which is called at resolution and receives the result as an argument.

See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

You might consider writing your function:

export function allEmp() {
  p = new Promise();

  let url = "employees?access_token=";
  ApiCall.getApiCall(url)
  .then(function (response) {
     console.log("result",result);    
     p.resolve({
                type: "ALL_EMP",
                payload: response})
            })
   .catch(function (error) {
      console.log("error",error);  
     p.reject(error)
   });

 return p  // allEmp now returns a promise which gives it a .then() method to contain your handler code.
 }

Then call your function like this:

allEmp().then(
 function(res){/*handle it here, not called until async resolves, receives result*/},
 function(err){/*or resolves to error, receives error*/}
 )

You might consider also having a look at the await/async syntax which makes it appear as if you code is waiting for async operations and can enhance readability in the majority of cases.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function