如何正确解析获取响应数组

时间:2018-12-31 19:07:58

标签: javascript async-await es6-promise fetch-api

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

  1. 获取并加载表单上的数据字段。
  2. 用户对一些可编辑字段进行编辑,然后点击保存
  3. 检查字段是否实际上已更改,然后映射要更新的字段
  4. 构建一组获取承诺(每个可编辑字段一个):PATCH用于每个可编辑字段的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函数中结合两个不同的步骤?

1 个答案:

答案 0 :(得分:0)

看起来不错,如果有什么要移动的地方,那就是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);
  });       
}