首页 > 解决方案 > Promise 没有按照它们被调用的顺序解决

问题描述

我正在将一个网站与 firebase 集成。我正在尝试从数据库中的用户集合中获取用户 ID,然后将每个用户 ID 传递给另一个函数,该函数从另一个集合中获取体验数据。我按名称对用户进行排序,因为我希望用户在我的页面上按字母顺序排序。代码按我的方式工作,只是承诺没有按正确的顺序解析,因此不按字母顺序输出。请参阅以下详细信息:

  1. 首先,我使用 getUserProfiles 函数获取用户。
  2. 我通过直接打印出每个索引(用户 [0]、用户 [1]、用户 [2])来确认每个用户 ID。
  3. 然后,我遍历每个用户,并在数据库查询前后记录用户 ID。
  4. 查看控制台日志,用户 ID 似乎以正确的顺序传递给数据库查询,但第二个 ID 在第一个 ID 之前解析。传递给数据库的第一个 ID 是“ZKnqtLVzUqNqdzX9f8ap76LThh32”。然而,“482uR9t2QEdCUi0Z4nq14VRVhEx1”首先解决

为什么 ID 没有按照传递的顺序解析?

    function getUserProfiles(){
      //get users, usernames and render profiles
        db.getUsers().then(users => {
          console.log('first index:', users[0].id);
          console.log('second index:', users[1].id);
          console.log('third index:', users[2].id);
          users.forEach(user => {
            db.getLatestExperience(user.id).then(()=>{

            })
        })  
    }

    Class {
        getLatestExperience(id, callback) {
          console.log('getLatestExperience before database request:', id);
          return this.experience.where('userID', '==', id).orderBy('start','desc').get().then(snapshot => {            
          console.log('getLatestExperience promise resolved', id);
        })        
      }

     getUsers(callback) {
       return this.users.orderBy('name').get().then(snapshot => {
            return snapshot.docs;
        })
      }
    }


    first index: ZKnqtLVzUqNqdzX9f8ap76LThh32
    second index: 482uR9t2QEdCUi0Z4nq14VRVhEx1
    third index: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
    getLatestExperience before database request: ZKnqtLVzUqNqdzX9f8ap76LThh32
    getLatestExperience before database request: 482uR9t2QEdCUi0Z4nq14VRVhEx1
    getLatestExperience before database request: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
    getLatestExperience promise resolved: 482uR9t2QEdCUi0Z4nq14VRVhEx1
    getLatestExperience promise resolved: ZKnqtLVzUqNqdzX9f8ap76LThh32
    getLatestExperience promise resolved: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2

标签: javascriptfirebaseasynchronouspromise

解决方案


您可以将 Promise 放在一个数组中,然后reduce将它们按顺序执行:

const promiseArray = [promise2, promise3...]
    promiseArray.reduce(
        (prev, next) => prev.then(prevResult => next(prevResult)), promise1())
            .then(finalResult => {...})

promiseArray是一个返回承诺的函数数组。你省略了第一个,因为你以后需要一个起始的。 Array.reduce将一个接一个地执行。 prev是您之前正在解决的承诺,如果需要,对于下一个承诺,您可以通过结果解决它并将其传递给下一个。最后,您可以使用最后一个 promise 的一个结果来解决整个 reduce。


推荐阅读