js 函数调用 returns 未定义

js function call returns undefined

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

我有一个这样的函数调用:

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?我想这与我在 axios 调用中 return 数组的方式有关,但我想不出另一种方法。

我也不想在函数中使用 setState,因为我调用了一些初始化函数,我宁愿在初始化所有数据后使用一个 setState .

提前致谢!

更新

我可以这样做吗:

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

您需要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);
        })
}

但是,函数现在 return 是一个 promise。你将不得不做类似的事情:

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

或者您可以使用 async/await

您需要从 initializeFoo 方法 return 但这会 return 数据的 Promise 而不是数据本身。

获取数据:

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

更新:

A Promise 是处理异步 activity 的巧妙方法。当您将 then 附加到 Promise 时,您实际上是在说 "As soon as this promise resolves THEN execute the following block"

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
  }
}