按顺序解决承诺不起作用

Resolving Promises sequentially not working

我有一个代码:

代码:

firebase.database().ref('someRef').limitToLast(3).on('value', snapshot => {
  let promiseArray = [];
  
  snapshot.forEach(e => {
    promiseArray.push(() => {
      firebase.storage().ref(e.key).getDownloadURL().then(url => {
        //Do something with URL
        //In this case, I print out the url to see the order of URL retrieved
        //Unfortunately, the order was incorrect
        return 'Resolved, please continue'; //Return something to resolve my Promise
      });
    });
  });
  
  let result = Promise.resolve([]);
  promiseArray.forEach(promise => {
    result = result.then(promise);
  });
});

我想应该已经是正确的了。但是,我想要得到的结果是错误的。我错过了什么?

编辑

我好像漏掉了一点。 在我的 Promise 数组中,我希望第一个函数先解析 Promise it returns,然后再继续第二个函数。

forEach是一种同步方法。您可以使用 map 创建承诺数组,然后使用 promise.all.

firebase.database().ref('someRef').limitToLast(3).on('value', snapshot => {
  let promiseArray = [];

  const promiseArray = snapshot.map(e => firebase.storage().ref(e.key).getDownloadURL());

  Promise.all(promiseArray).then((resultArr) => {
    // Do anything with your result array
  });
} 

对于承诺的顺序执行,您可以使用 async await

firebase.database().ref('someRef').limitToLast(3).on('value', async (snapshot) => {
    let promiseArray = [];

    const promiseArray = snapshot.map(e => firebase.storage().ref(e.key).getDownloadURL());
    let result;
    for(let i = 0; i < promiseArray.length; i++) {
        result = await promiseArray[i]; 
    }
});

你应该使用 reduce。你会在这里找到一个很好的例子:https://decembersoft.com/posts/promises-in-serial-with-array-reduce/

我想通了:显然,我忘了我的函数没有返回 Promise。因此,当我链接 then 时,它不会等待我的 Promise 先解决,因为它一开始甚至没有返回。我基本上是返回一个空值,因此函数会继续,而无需等待之前的 Promise 解决。只需添加 return 即可解决问题:

firebase.database().ref('someRef').limitToLast(3).on('value', snapshot => {
  let promiseArray = [];
  
  snapshot.forEach(e => {
    promiseArray.push(() => {
      return firebase.storage().ref(e.key).getDownloadURL().then(url => { //Add return here
        //Do something with URL
        //In this case, I print out the url to see the order of URL retrieved
        //Unfortunately, the order was incorrect
        return 'Resolved, please continue'; //Return something to resolve my Promise
      });
    });
  });
  
  let result = Promise.resolve([]);
  promiseArray.forEach(promise => {
    result = result.then(promise);
  });
});