js函数调用返回undefined

时间:2017-11-21 10:26:54

标签: javascript reactjs axios

我目前正在努力解决以下问题:

我有这样的函数调用:

foo = this.initializeFoo(id, array); // console.log() says: undefined

功能:

export function initializeFoo(id, array) {
    axios.get(API_URL + '/route/' + id)
        .then(response => {
            let copyPayload = [...response.data.foo];
            let copyArray = [...array];

        // Some operations  
            copyArray = copyArray.filter(x => {
                let exists = false;
                copyPayload.forEach(payload => {
                    if (x.id === payload.id) {
                        x["newAttribute"] = id;
                        exists = true;
                    }
                });
                return exists
            });

            console.log("Returning copyArray", copyArray); // Displays the proper data
            return copyArray;
        })
        .catch(error => {
            this.setState({loaded: false});
            console.log(error);
        })
}

问题是:为什么console.log() undefined?我想这与我在return调用中axios数组的方式有关,但我想不出另一种方法。

我也不想在函数中使用setState,因为我调用了一些初始化函数,并且在初始化所有数据之后我宁愿使用一个setState。 / p>

提前致谢!

更新

我可以这样做:

foo["blub"]  = this.initializeFoo(id, array).then(result => {
             return result;
        });

2 个答案:

答案 0 :(得分:3)

您需要return axios.get(API_URL + '/route/' + id)来电,如下所示

export function initializeFoo(id, array) {
    return axios.get(API_URL + '/route/' + id) // add return here
        .then(response => {
            let copyPayload = [...response.data.foo];
            let copyArray = [...array];

        // Some operations  
            copyArray = copyArray.filter(x => {
                let exists = false;
                copyPayload.forEach(payload => {
                    if (x.id === payload.id) {
                        x["newAttribute"] = id;
                        exists = true;
                    }
                });
                return exists
            });

            console.log("Returning copyArray", copyArray); // Displays the proper data
            return copyArray;
        })
        .catch(error => {
            this.setState({loaded: false});
            console.log(error);
        })
}

但是,该函数现在将返回一个promise。你必须做类似的事情:

return this.initializeFoo(id, array).then(result => {
    foo = result;
    console.log(foo)
}); // console.log() says: undefined

或者您可以使用async/await

答案 1 :(得分:1)

您需要从initializeFoo方法返回,但这将返回Promise数据,而不是数据本身。

获取数据:

this.initializeFoo(..args).then(copyArray => /* do something with the array */)

更新

Promise是处理异步活动的巧妙方法。当您将then附加到Promise时,您实际上是在说“一旦此承诺解决 那么 执行以下块”< / p>

let result = this.initializeFoo(..args).then(copyArray => copyArray)
// if you were to inspect `result` here, it would also be a `Promise`!

如果您仍然不使用.then,则可以使用async功能。这将允许您在函数中使用await,您实际上可以编写代码,就好像它是同步的一样。

async function initializeFoo(id, array) {
    let response = await axios.get(`${API_URL}/route/${id}`);
    // some operations on response
    let copyArray = this.massageResponse(response, array);

    // don't catch any exceptions here, let it bubble out...
    return copyData;
} 

现在,由于你不想在方法中setState,你必须从你调用它的地方做到这一点。

class MyComponent extends React.Component {

  componentDidMount() {
    // time to initialize data for this component
    this.initializeComponentData();
  }

  async function initializeComponentData() {
    // this function is called from `componentDidMount`
    try {
      let promiseOfBar = this.initializeFoo(id, array);

      // call another initializer 
      // - (this would have to be an async function as well)
      let promiseOfBaz = this.anotherInitalizer(id, array);  

      let foo = {};
      let response = await Promise.all(promiseOfBar, promiseOfBaz);
      foo['bar'] = response[0];
      foo['baz'] = response[1];

      // finally call `setState`
      this.setState({ ...foo, loaded: true });
    } catch (exception) {
      // catch any possible exceptions and `setState` accordingly
      this.setState({ loaded: false });
    }
  }

  // rest of the component 

  render() {
    // render logic
  }
}