如何正确解析一组 Fetch 响应

Posted

技术标签:

【中文标题】如何正确解析一组 Fetch 响应【英文标题】:How to properly parse an array of Fetch responses 【发布时间】:2019-05-28 04:14:41 【问题描述】:

在尝试实现使用户能够对某些数据进行部分更新的功能时,我提出了以下逻辑操作:

    在表单上获取和加载数据字段。 用户对某些可编辑字段进行编辑并点击保存 检查字段是否确实发生了变化,然后映射字段进行更新 构建一组提取承诺(每个可编辑字段一个:PATCHing 每个可编辑字段的 API 端点是不同的) 使用Promise.all,获取响应数组(承诺) 解析响应数组以获取我感兴趣的数据。

以下是我实际实现上述内容的方式:

 /*   EDIT RECORD
  * @param path: path to the record (ex: '/record/2')
  * @param fields: object containing fields to update (ex:  comment: "new comment here" )
  */
   async editRecord(path, fields) 
     const responsePromises = await Promise.all(
       Object.keys(fields).map(field =>                 // create an array of a number of fetch requests detemined by number of fields
         this.patchRecord(path, field, fields[field])      // returns a fetch request
       )
     ).then(res => res.map(each => each.json()));       // return  an array of "json decoded"?? response promises  


  /*
   * For each response promise:
   *  1. Grab a message or an errorlist
   *  2. Append the message, or list of errors to an object holding the errors/messages of already parsed responses
   */
    const  errors, messages  = await responsePromises.reduce(
      async (parsedObjectPromise, response) => 
        const parsedObject = await parsedObjectPromise;
        const  data, errors: responseErrors  = await response;
        let message;

        if (data) [message] = data;

        if (responseErrors) parsedObject.errors.push(...responseErrors);
        if (message) parsedObject.messages.push(message);

        return parsedObject;
      ,
       errors: [], messages: [] 
    );

    console.log(errors, messages);
  ,




  /*
   *  Returns a fetch request for one datafield update
   * @param path: path to the record (ex: '/record/2')
   * @param field: field to update (ex: 'comment')
   * @param value: value to update field with  (ex: 'new comment')
   */   

  patchRecord(path, field, value) 
    let requestUrl = IR_HELPERS.buildFetchPath( singleRecordPath: path );
    requestUrl += `/$field`;   // ex: 127.0.0.1:2343/record/2/comment

    return fetch(requestUrl, 
      method: 'PATCH',
      headers: 
        Accept: 'application/json',
        Authorization: `Bearer $IR_HELPERS.token`,
        'Content-Type': 'application/json',
      ,
      body: JSON.stringify( [field]: value ),
    );
  ,

这很好用,但为了清楚起见:

    这种方法是否合理或者是否有更好的方法来实现上述方法? 如何在editRecord 函数中组合两个不同的步骤?

【问题讨论】:

【参考方案1】:

看起来不错,如果有什么要移动的,那就是 responsePromises.reduce,直到 then 块,或者让那个将映射的响应返回到新的 then 块中。

/*   EDIT RECORD
  * @param path: path to the record (ex: '/record/2')
  * @param fields: object containing fields to update (ex:  comment: "new comment here" )
  */
async editRecord(path, fields) 
  Promise.all(
    Object.keys(fields).map(field => 
      this.patchRecord(path, field, fields[field]))
  )
  .then(res => res.map(each => each.json()))
    /*
     * For each response promise:
     *  1. Grab a message or an errorlist
     *  2. Append the message, or list of errors to an object holding the errors/messages of already parsed responses
     */
  .then(responsePromises => responsePromises.reduce(
    async (parsedObjectPromise, response) => 
      const parsedObject = await parsedObjectPromise;
      const  data, errors: responseErrors  = await response;
      let message;

      if (data) [message] = data;

      if (responseErrors) parsedObject.errors.push(...responseErrors);
      if (message) parsedObject.messages.push(message);

      return parsedObject;
    ,
     errors: [], messages: [] 
  ))
  .then(( errors, messages ) => 
    console.log(errors, messages);
  );       

【讨论】:

以上是关于如何正确解析一组 Fetch 响应的主要内容,如果未能解决你的问题,请参考以下文章

Javascript - 如何知道Fetch API中的响应类型?

如何从“await fetch()”解析 Promise?

如何使用 Redux Thunk 处理 fetch() 响应中的错误?

如何以正确的方式解析来自 GET 响应的数据?

如何在 TypeScript 中使用 fetch

如何从 fetch 中获取响应的标头