如何正确解析 Fetch 响应数组

How to properly parse an array of Fetch responses

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

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

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

 /*   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 }),
    });
  },

这工作正常,但为了清楚起见:

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

看起来不错,如果有什么要移动的,那就是 responsePromises.reduce,向上移动到 then 块,或者将那个 return 映射的响应放入新 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);
  });       
}