Promise.all 的 then() 函数在 Promise 完成之前执行 - Ionic/Angular

Posted

技术标签:

【中文标题】Promise.all 的 then() 函数在 Promise 完成之前执行 - Ionic/Angular【英文标题】:then() function of Promise.all executing before promises are finished - Ionic/Angular 【发布时间】:2018-04-05 21:19:05 【问题描述】:

我第一次使用ionic 设置缓存。代码如下:

listProducts(): Promise < any > 
    let cacheKey = 'products';
    this.cache.removeItem(cacheKey);
    let promises_array:Array<any> = [];
    let results;
    return new Promise((resolve, reject) => 
        this.cache.getItem(cacheKey).catch(() => 
            this.list = this.af.list('/products');
            this.subscription5 = this.list.subscribe(items => 
                for (let x = 0; x < items.length; x++) 
                    promises_array.push(new Promise((resolve, reject) => 
                        console.log(JSON.stringify(items[x].customMetadata) + ":   this is the customdata (((()()()()()");
                        let storageRef = firebase.storage().ref().child('/settings/' + items[x].customMetadata.username + '/profilepicture.png');
                        storageRef.getDownloadURL().then(url => 
                            console.log(url + "in download url !!!!!!!!!!!!!!!!!!!!!!!!");
                            items[x].customMetadata.profilepic = url;
                        ).catch((e) => 
                            console.log("in caught url !!!!!!!$$$$$$$!!");
                            items[x].customMetadata.profilepic = 'assets/blankprof.png';
                        );
                        //this.startAtKey = item.$key;
                        this.productListArray.push(items[x].customMetadata);
                    ));
                ;
            )
            results = Promise.all(promises_array);
            results.then(() => 
                //setTimeout(() => 
                console.log(JSON.stringify(this.productListArray) + " value value vlaue productlistarray");
                this.productListArray.reverse();
                return this.cache.saveItem(cacheKey, this.productListArray);
                //, 3000);
            )
        ).then(data => 
            console.log("Saved data: ", data);
            resolve();
        )
    )

基本上console.log(JSON.stringify(this.productListArray) + " value value vlaue productlistarray"); 行打印一个空数组-[]。这个变量中应该有数据,因为代码不应该在所有承诺完成之前执行。你会注意到我有一个setTimeout 被注释掉了——当我评论它时,它起作用了——但这显然不是一个可接受的解决方案,我只是表明它是一个与承诺有关的时间问题。任何帮助都会很棒。

【问题讨论】:

【参考方案1】:

我认为问题出在这一行

this.list.subscribe(items => 

基本上,列表仍然在获取时

console.log(JSON.stringify(this.productListArray) + " value...

正在运行。所以我希望promises_array 是空的(你可以检查一下)。

您可以通过将list(map() 或 flatMap(),需要检查哪个)映射到一个 promise 数组而不是推入单个 promise 来解决这个问题。

我认为这是地图(或 flatMap)代码,但需要测试。请注意,每个缩进级别都需要大量返回。

const promises_array = this.list.map(items => 
  return items.map(item => 
    return new Promise((resolve, reject) => 
      console.log(JSON.stringify(items[x].customMetadata) + ":   this is the customdata (((()()()()()");
      let storageRef = firebase.storage().ref().child('/settings/' + items[x].customMetadata.username + '/profilepicture.png');
      return storageRef.getDownloadURL().then(url => 
        console.log(url + "in download url !!!!!!!!!!!!!!!!!!!!!!!!");
        items[x].customMetadata.profilepic = url;
      ).catch((e) => 
        console.log("in caught url !!!!!!!$$$$$$$!!");
        items[x].customMetadata.profilepic = 'assets/blankprof.png';
      );
      this.productListArray.push(items[x].customMetadata);
    ));    
  )

Promise.all(promises_array)
  .then(() => 
    console.log(JSON.stringify(this.productListArray) + " value value vlaue productlistarray");
    this.productListArray.reverse();
    this.cache.saveItem(cacheKey, this.productListArray);
)

【讨论】:

非常感谢...我实际上在我的应用程序的其他地方使用过这种技术...我试试看 - 我很确定你是对的,我记得以前遇到过这个问题

以上是关于Promise.all 的 then() 函数在 Promise 完成之前执行 - Ionic/Angular的主要内容,如果未能解决你的问题,请参考以下文章

React Native 为啥我的代码在完成任务之前执行? Promise.all().then() 异步问题

Promise.all函数的使用

.then() 在嵌套的 promise.all 和 fetch 完成之前执行

.then 的 Promise.all 没有执行

Promise.prototype.then()学习

Promise.all( ) 的使用