代码之家  ›  专栏  ›  技术社区  ›  Craig

正在尝试从fetch Promise获取“status”数据

  •  0
  • Craig  · 技术社区  · 6 年前

    我正在尝试为我的React项目创建一个通用的Fetch方法。计划是将url和一些配置数据(方法、头等)传递给fetch方法。然后将较少的技术数据返回给我的调用方法。我想返回来自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);
        });
    

    我的控制台日志记录“response”,包含来自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

    我想我误解了这里的承诺。(我对他们很在行)。

    使用我的获取方法的数据访问器:

     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类?我想我只是把承诺搞砸了。。。但不确定这里的最佳模式。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Grogi    6 年前

    这里的问题是 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/await函数呢?所有浏览器都支持这个阶段。。。

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

    请注意,在这两种情况下,函数都会返回另一个承诺。

        2
  •  1
  •   Mario Santini Imran Kedim    6 年前

    我想你可以用 承诺。决心 ,链接承诺以获取结果对象:

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

    这个 可以将Promise作为参数并返回一个Promise,该Promise将扁平化链,因此您可以获得json解析的值并使用它。

        3
  •  1
  •   Raghav Garg    6 年前

    你需要进一步解决 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 ,因为它是多余的。