在 Vue 组件中链接不同的 API 调用,包括一个带有 for 循环的调用

Chaining different API calls in a Vue component including one with a for loop

我试图了解如何链接两个不同的 API 调用,包括一个在“notes”Vue 组件中带有 for 循环的调用。我对 promises 有非常基本的体验,我正在寻求改进。

我正在第一个 API 调用以获取所有笔记并使用 Vuex 突变将它们推送到数组中。在第一个 API 调用期间,我还将不同用户的电子邮件映射到一个对象中。

使用此映射对象,我在 for 循环内进行第二次 API 调用以获取所有用户头像。

这是第一个 API 调用的样子:

getAllNotesAPI(entity) {
  noteService.getNotes(entity)
    .then((response) => {

      if (response.data.length === '0') {
        // Set hasData to false if the response is 0
        this.hasData = false;
      } else {
        // Push data into the note array using a store mutation
        this.setAllNotes(response.data);
      }

      // Mapping all users emails into 'userEmails'
      this.userEmails = [...new Set(response.data.map(x => x.userEmail))];

      // Calling my second API call here to get all the avatars associated with these emails
      for (let i = 0; i < this.userEmails.length; i++) {
        this.getAvatarAPI(this.userEmails[i])
      }
    })
    .catch((error) => {
      console.log(error);
    })
    .finally(() => {
      this.endLoader('notes');
    });
},

this.getAvatarAPI 是第二个 API 调用,如下所示:

getAvatarAPI(login) {
  userService.getAvatar(login)
    .then((response) => {

      let newAvatar = {
        userEmail: login,
        picture: response.data.picture
      };
      // Push the response into a userAvatar Object using a store mutation
      this.setUserAvatar(newAvatar);
    }).catch((error) => {
      console.log(error)
  })
},

我试过使用 async / await 但无法弄清楚如何将其绑定到异步函数中(this.getAvatarAPI(this.userEmails))未定义,我试过链接然后使用倍数但无法弄清楚如何:获取我所有的笔记然后我所有的化身然后在这两个 API 调用完成后结束 'note' 加载程序。

如果你们中的任何人能给我一些指示或答案的开头,我将不胜感激!

首先,虽然与您的问题无关,但在不必要时避免循环:

您需要 i 索引吗?

  for (let i = 0; i < this.userEmails.length; i++) {
    this.getAvatarAPI(this.userEmails[i])
  }

没有。您需要用户邮箱。那么

  this.userEmails.forEach(userMail => {
    this.getAvatarAPI(userEmail)
  })

现在,要同步 promise,您需要 return 一个 promise(暂且不谈异步)

  1. 让 getAvatarAPIreturn 成为承诺
getAvatarAPI(login) {
  return userService.getAvatar(login).then(blabla) // notice the return here
  1. 取回 getAvatar 的承诺 API
  let promises = this.userEmails.map(userMail => {
    return getAvatarAPI(userEmail)
  })
  1. return所有承诺都兑现后
  let promises = this.userEmails.map(userMail => {
    return getAvatarAPI(userEmail)
  })
  return Promise.all(promises)

附注 async/await

如果你使用它,你不再被迫写return,你需要写async/await,但

基本思想保持不变。指定 async 关键字表示您的函数将 return 类似 promise。

例如

  async function p () {
    return 5
  }

  p.then(x => console.log(x)) // does print 5 even though we didn't explicitely write return Promise.resolve(5)

现在您必须确保在调用异步函数时等待它:

  getAvatarAPI: async login => {
    return userService.getAvatar(login).then(blabla)
  }

  // DO NOT do it
  this.userEmails.forEach(userMail => {
    return await this.getAvatarAPI(userEmail)
  })

在上面的 forEach 循环中,您将在 sequence 中执行 getAvatarAPI 调用,因为 await "stops" 迭代只要 getAvatarAPI还没有解决。

正确的方法是

  getAllNotesAPI: async entity => {
    try { // notice the necesary try-catch block
      const response = await noteService.getNotes(entity)
      blabla
      let promises = this.userEmails.map(userMail => {
        return this.getA...
      })
      let result = await Promise.all(promises)
      // eventually return result, or simply await Promise... without lefthand-side assignment
    } catch (error) {
      console.log(error);
    }
    console.log(this.end('loader'))
  }