JavaScript / React - 在函数内返回Promise

时间:2017-04-17 22:11:40

标签: javascript reactjs promise

我在应用中遇到一些Promise时遇到一些麻烦,任何澄清都会非常感激。

我已根据本教程松散地构建了一个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);
});

这很好用。

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

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;

Login.jsx

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

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

如果我在console.log(json)中的return语句之前添加parseResponse(),我确实看到了我的数据并且看起来不错......但是如何从Promise中获取数据呢?进入我的组件?在我看来,我也需要将post()定义为承诺,但我不确定如何构建它。

1 个答案:

答案 0 :(得分:6)

  

但是这不起作用的原因是因为fetch()是一个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)
    }
}

现在post也会返回承诺。

如果你没有返回,隐式返回值将是undefined,因此错误消息“Uncaught TypeError:无法读取属性”,然后是“未定义”< / em>的

此错误最简单的重复案例:

function foo(){}

foo().then();