如何从fetch()承诺返回数据?

时间:2017-12-02 02:43:26

标签: javascript react-native

我无法绕过在一个函数中从fetch()调用返回json数据,并将该结果存储在另一个函数内的变量中。这是我对我的API进行fetch()调用的地方:

function checkUserHosting(hostEmail, callback) {
    fetch('http://localhost:3001/activities/' + hostEmail)
    .then((response) => { 
        response.json().then((data) => {
            console.log(data);
            return data;
        }).catch((err) => {
            console.log(err);
        })
    });
}

这就是我试图获得返回结果的方式:

function getActivity() {
    jsonData = activitiesActions.checkUserHosting(theEmail)
}

但是,jsonData始终是undefined(我假设这是因为在尝试将返回值分配给jsonData时,异步提取调用尚未完成。我该如何等待足够长的时间从fetch调用返回数据,以便我可以正确地将它存储在jsonData内?

3 个答案:

答案 0 :(得分:2)

你是对的。这是因为你试图以同步的方式获得这个异步调用的结果。执行此操作的唯一方法与处理任何其他承诺的方式相同。通过.then回调。所以对于你的片段:

function getActivity() {
    return activitiesActions.checkUserHosting(theEmail).then((jsonData) => {
        // Do things with jsonData
    })
}

依赖于异步操作的任何函数本身必须变为异步。因此,对于需要使用.then函数的任何内容,无法避免使用checkUserHosting

答案 1 :(得分:2)

如果你想让它工作,也总是return承诺: - checkUserHosting应该返回一个承诺 - 在您的情况下,return promise return结果data

function checkUserHosting(hostEmail, callback) {
    return fetch('http://localhost:3001/activities/' + hostEmail)
        .then((response) => { 
            return response.json().then((data) => {
                console.log(data);
                return data;
            }).catch((err) => {
                console.log(err);
            }) 
        });
}

并在主代码中的.then()中捕获它:

function getActivity() {
    let jsonData;
    activitiesActions.checkUserHosting(theEmail).then((data) => {
       jsonData = data;
    }        
}

编辑:

甚至更好,使用@Senthil Balaji建议的新语法:

const checkUserHosting = async (hostEmail, callback) => {
 let hostEmailData  = await fetch(`http://localhost:3001/activities/${hostEmail}`)
 //use string literals
 let hostEmailJson = await hostEmailData.json();
 return hostEmailJson;
}

const getActivity = async () => {
 let jsonData = await activitiesActions.checkUserHosting(theEmail);
  //now you can directly use jsonData
}

答案 2 :(得分:0)

您可以使用新的ES6和Es7语法以及其他人编写的内容也是正确的,但这可以更加可读和干净,

你试图同步获取aysnc值,这里jsonData将是未定义的,因为你在异步函数(checkUserHosting)完成执行之前移动到下一行执行,这可以写成如下

const getActivity = async () => {
 let jsonData = await activitiesActions.checkUserHosting(theEmail);
  //now you can directly use jsonData
}

您可以使用新的语法(例如

)以不同的方式编写checkUserHosting
const checkUserHosting = async (hostEmail, callback) => {
 let hostEmailData  = await fetch(`http://localhost:3001/activities/${hostEmail}`)
 //use string literals
 let hostEmailJson = await hostEmailData.json();
 return hostEmailJson;
}