尝试从获取Promise获取数据的“状态”

时间:2018-10-13 07:21:14

标签: javascript reactjs

我正在尝试为我的React项目制作一个通用的Fetch方法。计划是向我的提取方法传递一个url和一些配置数据(方法,标头等)。然后将较少的技术数据返回给我的调用方法。我想从api调用返回数据,而有效载荷就是json数据。

return fetch(URL, config)
    .then((response) => {
      console.log('Fetch - Got response: ', response);
      return response;
    })
    .then((response) => {
      console.log('Json: ', response.status);
      const result = { data: response.json(), status: response.status };
      return result;
    })
    .catch((e) => {
      console.log(`An error has occured while calling the API. ${e}`);
      reject(e);
    });

这是我最初的尝试,但我不确定自己在做什么。

我的控制台日志记录了“响应”,其中包含来自API调用的响应:

body: (...)
bodyUsed: true
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:49487//api/xxx/yyy"

API调用完成,并且我的状态为200。

该行:

console.log('Json: ', response.status);

按预期返回200。

我以前一直在做

return response.json()

然后我的主班获得了薪水,但没有任何身份。我想做的是返回我的有效载荷以及状态。

所以我试图将其更改为此:

  const result = { data: response.json(), status: response.status };
  return result;

但是我的通话应用程序现在看到:

data: Promise {<resolved>: Array(9)}
status: 200

我希望获取数据:MyPayloadArray,状态:200

我认为我在这里误解了诺言。 (我对他们很环保)。

使用Fetch方法的数据访问器:

 static GetAll() {
    return new Promise((resolve, reject) => {
      const request = {
        method: 'GET',
        URL: `${Server.ApiURL}/api/admin/clients`,
      };

      fetchData(request)
        .then((result) => {
          console.log('GetAll sees response as ', result);
          resolve(result);
        })
        .catch((error) => {
          reject(new Error(error));
        });
    });
  }

我试图像这样调用数据访问器类:

componentDidMount() {
ClientDataAccessor.GetAll()
  .then((response) => {
    console.log('Got list!', response);
    this.setState({ clients: response, isLoading: false });
  })
  .catch((error) => {
    console.log('Got error on list screen', error);
  });

}

如何仅获取状态,并将有效负载返回到DataAccesor类?我想我只是搞砸了Promises ...,但是不确定这里的最佳模式。

我要去UI类,onComponentDidMount-> DataAccessor.GetAll-> FetchData。我想我在某个地方滥用Promise。

3 个答案:

答案 0 :(得分:2)

这里的问题是response.json()返回了另一个承诺。您必须自己解决该诺言对象,然后返回您要寻找的对象。

return fetch(URL, config)
.then((response) => {
  console.log('Fetch - Got response: ', response);
  return response;
})
.then((response) => 
   response.json()
   .then( (data) => { data, status: response.status } )
)
.catch((e) => {
  console.log(`An error has occured while calling the API. ${e}`);
  reject(e);
});

非常丑...

为什么不将其移至异步/等待功能?目前所有浏览器都支持它...

async myFetch(URL, config) {
   try {
      const response = await fetch(URL, config);
      console.log('Fetch - Got response:', response);

      const data = await response.json();
      console.log('Fetch - Got data:', data);

      return { data, status: response.status }
   }
   catch (e) {
      console.error(`An error has occured while calling the API. ${e}`);
      throw e;
   }
}

在两种情况下,请注意您的函数都会返回另一个promise。

答案 1 :(得分:1)

我认为您可以使用 Promise.resolve 来解决您的问题,链接保证以获得您的结果对象:

...
.then(response => {
    var status = response.status;
    return Promise.resolve(response.json())
           .then(data => ({ data, status }))
})

Promise.resolve 可以将Promise作为参数,并返回将使链扁平化的promise,因此您可以获得json parse的值并使用它。

答案 2 :(得分:1)

您需要进一步解决res.json()才能获取信息。您可以执行以下操作:

return fetch(URL, config)
    .then((response) => {
      console.log('Fetch - Got response: ', response);
      return response;
    })
    .then(response =>
      response.json().then(json => ({
        status: response.status,
        json
      })
    ))
    .then(({ status, json }) => {
      console.log({ status, json });
      return { data: json, status: status };
    })
    .catch((e) => {
      console.log(`An error has occured while calling the API. ${e}`);
      reject(e);
    });

上面的简洁版本可以是:

return fetch(URL, config)
    .then(response => response.json()
      .then(json => ({ status: response.status, data: json }) )
    )

注意:因为它是多余的,因此从reject(e)内部删除了catch