JavaScript/React - 在函数内返回Promise

skw*_*eth 1 javascript promise reactjs

我在应用程序中处理一些Promises时遇到一些麻烦,任何澄清都会非常感激.

我一直在根据本教程松散地构建Phoenix/React应用程序 - https://medium.com/@benhansen/lets-build-a-slack-clone-with-elixir-phoenix-and-react-part-3 -frontend-authentication-373e0a713e9e - 我正在尝试重构我的代码,以便我将来更容易构建应用程序的其他方面.

最初,当将登录数据发布到我的Phoenix服务器时,我使用的功能看起来像这样(来自Login.jsx):

fetch(`${apiUrl}/sessions`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({person: person})
}).then(response => {
   this.setState({loadingData: false}, () => {
     response.json().then(result => {
        if(result.status === "error"){
          this.setState({error: {isError: true, message: result.message}}, () => {
            return;
          })
        }
        else{
          this.login(result) //DO SOME OTHER STUFF WITH THE RESULT
        }
     })
   })
}).catch(error => {
   console.error("There was an error: " + error);
});
Run Code Online (Sandbox Code Playgroud)

这工作得很好.

但是,我已经重新构建了我的代码,以便将获取功能移动到另一个文件中.以下是它现在的样子(有点类似于教程):

fetch.js

let parseResponse = (response) => {
    return response.json().then((json) => {
        if (!response.ok){
            return Promise.reject(json)
        }
        return json;
    });
}

let fetchFunctions = {
    post: (url, data) => {
        const body = JSON.stringify(data)
        fetch(`${apiUrl}${url}`, {
            method: 'POST',
            headers: headers(),
            body: body
        })
        .then(parseResponse)
    }
}

export default fetchFunctions;
Run Code Online (Sandbox Code Playgroud)

Login.jsx

post('/sessions', {person: person})
  .then((result) => {
      this.login(result) //HERE'S THAT LOGIN FUNCTION I WANT TO RUN
})
Run Code Online (Sandbox Code Playgroud)

现在,当我运行这个时,你可能不会惊讶地发现我得到了错误Uncaught TypeError: Cannot read property 'then' of undefined,而且我明白了...我想...如果我错了请纠正我,但是这不起作用的原因是因为fetch()是一个Promise,但我现在把它包装在一个不是Promise的函数中.

如果我console.log(json)在return声明之前添加parseResponse(),我确实看到了我的数据,它看起来不错......但是如何从Promise和我的组件中获取数据?在我看来,我也需要定义post()为Promise,但我不确定如何构建它.

Fel*_*ing 6

但是这不起作用的原因是因为fetch()是一个Promise,但我现在把它包装在一个不是Promise的函数中.

功能不是承诺.函数可以返回 promise.你只是忘了从以下方面返回结果fetch,这是一个承诺post:

let fetchFunctions = {
    post: (url, data) => {
        const body = JSON.stringify(data)
        return fetch(`${apiUrl}${url}`, {
    //  ^^^^^^
            method: 'POST',
            headers: headers(),
            body: body
        })
        .then(parseResponse)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在也post返回一个承诺.

如果你没有返回,隐式返回值将是undefined,因此错误消息"Uncaught TypeError:无法读取属性'然后' 未定义 "

这个错误的最简单的repro案例:

function foo(){}

foo().then();
Run Code Online (Sandbox Code Playgroud)