Javascript 返回对象内部的fetch.json。

Javascript 返回对象内部的fetch.json。,javascript,promise,fetch,es6-promise,Javascript,Promise,Fetch,Es6 Promise,我有一个API调用函数,希望在单个对象中同时返回response.json()内容和response.status 像这样: const getData = data => { return fetch('/api_endpoint',{ method: 'GET', headers: { 'Content-type': 'application/json' } }) .then(response => {

我有一个API调用函数,希望在单个对象中同时返回response.json()内容和response.status

像这样:

  const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response => {
        return { 
                  body: response.json(), 
                  status: response.status 
               }
    })
}
问题是response.json()是一个承诺,所以在解决它之前我无法提取它的值

我可以这样做:

  const getData = data => {
  let statusRes = undefined;
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response => {
        statusRes = response.status;
        return response.json()
    })
  .then(data => {
      return {
          body: data,
          status: statusRes
      }
    }
  )
}

但这感觉不对。有人有更好的主意吗?

如果变量让您感到不安,您可以返回元组(ES中的数组)

在这种情况下,变量已足够节省,因为它只在同一个promise堆栈中使用一次

const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response =>
    //promise all can receive non promise values
    Promise.all([//resolve to a "tuple"
      response.status,
      response.json()
    ])
  )
  .then(
    /**use deconstruct**/([status,body]) =>
    //object literal syntax is confused with
    //  function body if not wrapped in parentheses
      ({
          body,
          status
      })
  )
}
或者按照约瑟夫的建议去做:

const getData = data => {
  return fetch('/api_endpoint',{
      method: 'GET',
      headers: {
          'Content-type': 'application/json'
      }
  })
  .then(response =>
      response.json()
      .then(
        body=>({
          body,
          status:response.status
        })
      )
  )
}
更新

在这里,我想解释一下为什么使用wait会导致函数做得太多。如果您的函数看起来很难看,并使用wait解决它,那么您的函数很可能一开始做了太多的工作,而您没有解决根本的问题

假设您的json数据有日期,但json中的日期是字符串,您希望发出请求并返回body/status对象,但body需要有真实的日期

这方面的一个示例可以通过以下内容进行演示:

typeof JSON.parse(JSON.stringify({startDate:new Date()})).startDate//is string
你可以说你需要一个函数:

  • 从URL到响应承诺
  • 从回应承诺到客体承诺
  • 从标的物承诺到标的物承诺及实际日期
  • 从带有实际日期的对象的响应和承诺到身体/状态的承诺
  • 假设url是类型a,响应承诺是类型b,以此类推。那么您需要以下内容:

    typeof JSON.parse(JSON.stringify({startDate:new Date()})).startDate//is string
    
    a->b->c->d;[b,d]>e

    与其编写一个函数去
    a->e
    ,不如编写4个函数:

  • a->b
  • b->c
  • c->d
  • [b,d]>e
  • 您可以使用promise chain
    1将输出从1输送到2,从2输送到3。然后(2)。然后(3)
    问题是函数2得到的响应直到函数4才使用

    这是组合函数来执行类似
    a->e
    的操作的常见问题,因为
    c->d
    (设置实际日期)不关心响应,而
    [b,d]->e
    关心响应

    这一常见问题的解决方案可以是函数的线程结果(我不确定函数编程中的正式名称,如果您知道,请告诉我)。在函数式程序中,您有类型(a、b、c、d、e)和从类型a到b或从类型b到c的函数。。。对于a到c,我们可以组成a到b和b到c。但是我们也有一个从tuple
    [b,d]
    e

    如果查看第四个函数
    object和responsetoobjectandstatusobject
    ,它使用一个名为
    thread
    的实用程序(使用
    createThread
    创建)获取响应(第一个函数的输出)和带有日期的对象(第三个函数的输出)的元组

    //这将进入实用程序函数库
    const promiseLike=val=>
    (val&&typeof val.then==“函数”);
    常量替换={};
    const SAVE={}
    const createThread=(saved=[])=>(fn,action)=>arg=>{
    const processResult=result=>{
    const addAndReturn=结果=>{
    (action==SAVE)?saved=saved.concat([result]):false;
    (操作===替换)?已保存=[结果]:false;
    返回结果;
    };
    回报(承诺(结果))
    ?结果。然后(添加和返回)
    :addAndReturn(结果)
    }
    返回(类允诺(arg))
    ?arg.那么(
    结果=>
    fn(保存的.concat([result]))
    )
    。然后(处理结果)
    :processResult(fn(保存的.concat([arg]))
    };
    const jsonWithActualDates=keyIsDate=>object=>{
    const recur=object=>
    Object.assign(
    {},
    对象
    对象。键(对象)。减少(
    (o,键)=>{
    (对象[键]&(对象的类型[键]=“对象”))
    ?o[键]=重复(对象[键])
    :(钥匙日期(钥匙))
    ?o[键]=新日期(对象[键])
    :o[key]=对象[key];
    返回o;
    },
    {}
    )
    );
    返回重现(对象);
    }
    const testJSON=JSON.stringify({
    开始日期:新日期(),
    其他:“其他价值”,
    范围:{
    最小值:新日期(Date.now()-100000),
    最大值:新日期(Date.now()+100000),
    其他:22
    }
    });
    //特定于应用程序的实现库(类型a到b)
    const urltoreponse=url=>//a->b
    承诺,决心({
    现状:200,
    json:()=>json.parse(testJSON)
    });
    const responseToObject=response=>response.json()//b->c
    const objectWithDates=object=>/c->d
    jsonWithActualDates
    (x=>x.toLowerCase().indexOf(“日期”)!=-1 | | x==“最小值”| | x==“最大值”)
    (对象);
    const objectAndResponseToObjectAndStatusObject=([response,object])=>/d->e
    ({
    主体:客体,,
    状态:response.status
    });
    //实际工作流程
    const getData=(url)=>{
    const thread=createThread();
    返回承诺。解析(url)
    .then(线程(urltoreresponse,SAVE))//保存响应
    .then(responseToObject)//不使用线程值
    .then(objectWithDates)//不使用线程化值
    .然后(线程(objectAndResponseToObjectAndStatusObject))//使用线程值
    };
    getData(“某个url”)
    .那么(
    results=>console.log(结果)
    
    );如果变量困扰您,则无需使用它,您可以返回元组(ES中的数组)

    在这种情况下,变量已足够节省,因为它只在同一个promise堆栈中使用一次

    const getData = data => {
      return fetch('/api_endpoint',{
          method: 'GET',
          headers: {
              'Content-type': 'application/json'
          }
      })
      .then(response =>
        //promise all can receive non promise values
        Promise.all([//resolve to a "tuple"
          response.status,
          response.json()
        ])
      )
      .then(
        /**use deconstruct**/([status,body]) =>
        //object literal syntax is confused with
        //  function body if not wrapped in parentheses
          ({
              body,
              status
          })
      )
    }
    
    或者按照约瑟夫的建议去做:

    const getData = data => {
      return fetch('/api_endpoint',{
          method: 'GET',
          headers: {
              'Content-type': 'application/json'
          }
      })
      .then(response =>
          response.json()
          .then(
            body=>({
              body,
              status:response.status
            })
          )
      )
    }
    
    更新

    在这里,我想解释一下为什么使用wait会导致函数做得太多。如果您的函数看起来很难看,并使用wait解决它,那么您的函数很可能一开始做了太多的工作,而您没有解决根本的问题

    假设您的json数据有日期,但json中的日期是字符串,您希望发出请求并返回body/status对象,但body需要有真实的日期