【问题标题】:code in promise .then firing way before promise finishes承诺中的代码。然后在承诺完成之前触发方式
【发布时间】:2018-05-09 09:31:27
【问题描述】:

我有这个代码...抱歉我已经有一段时间的混乱:

loadAvailabilities() {

    let promises = [];
    let promises2 = [];
    let indexi = 0;
    //return new Promise((resolve, reject) => {
      this.appointments = this.af.list('/appointments', { query: {
        orderByChild: 'selected',
        limitToFirst: 10
      }});
      let mapped;
      this.subscription2 = this.appointments.subscribe(items => items.forEach(item => {
        //promises.push(new Promise((resolve, reject) => {
          console.log(item);
          let userName = item.$key;
          //this.availabilities = [];
          for(let x in item) {
            let month = x;
            console.log(x + "      month");

            this.appointmentsMonth = this.af.list('/appointments/' + userName + '/' + month);
            this.subscription3 = this.appointmentsMonth.subscribe(items => items.forEach(item => {
                this.startAtKeyAvail = item.$key;
                //console.log(JSON.stringify(item) + "           item");
                let date = new Date(item.date.day * 1000);
                let today = new Date();
                console.log(date.getMonth() + "==" + today.getMonth()  + "&&" + date.getDate() + "==" + today.getDate());
                console.log("IN LOAD AVAILABILITIES *(*((**(*(*(*(*(*(*&^^^^%^%556565656565");
                if(date.getMonth() == today.getMonth() && date.getDate() == today.getDate()) {
                  console.log("            inside the if that checks if its today");
                  console.log(item.reserved.appointment + "                *************appointment");
                  //let counter = 0;
                  //mapped = item.reserved.appointment.map((r) => {
                  //item.reserved.appointment.forEach((r, index) => {
                    for(let r of item.reserved.appointment) {
                      promises.push(new Promise((resolve, reject) => {
                        if(r.selected == true) {
                          //this.renderer.setElementStyle(this.noavail.nativeElement, 'display', 'none');

                          let storageRef = firebase.storage().ref().child('/settings/' + userName + '/profilepicture.png');

                          let obj = {'pic':"", 'salon': userName, 'time': r.time};

                          storageRef.getDownloadURL().then(url => {
                            console.log(url + "in download url !!!!!!!!!!!!!!!!!!!!!!!!");
                            obj.pic = url;
                            this.availabilities.push(obj);
                            console.log(JSON.stringify(this.availabilities));
                            resolve();
                          }).catch((e) => {
                            console.log("in caught url !!!!!!!$$$$$$$!!");
                            obj.pic = 'assets/blankprof.png';
                            this.availabilities.push(obj);
                            console.log(JSON.stringify(this.availabilities));
                            resolve();
                          });
                        }
                      }))

                  }

                }

               }))
             }
          }))
            //}));

          Promise.all(promises).then(() => {
            console.log("in load availabilities ......... ")
            console.log(JSON.stringify(this.availabilities));

            this.availabilities.sort(function(a,b) {
              return Date.parse('01/01/2013 '+a.time) - Date.parse('01/01/2013 '+b.time);
            });

            console.log('*****previous******');
            console.log(JSON.stringify(this.availabilities));
            console.log('*****sorted********');

            for(let i of this.availabilities) {
              console.log(i.time + "          this is itime");
              let date = new Date('01/01/2013 ' + i.time);
              console.log(date + "          this is date in idate");
              let str = date.toLocaleTimeString('en-US', { hour: 'numeric', hour12: true, minute: 'numeric' });
              console.log(str);
              i.time = str;
            }
          });
      //}))



    //})

  }

我可以从日志消息中得知storageRef.getDownloadURL() 函数在我的页面加载结束时发生...这是对象实际被推送到this.availabilities 的位置(最终用于填充列表)。 Promise.all .then() 中的代码实际上会在任何内容被推送到 this.availabilities 之前触发,因此当排序发生时,它是一个空数组,没有任何内容被排序。

【问题讨论】:

  • 而不是为这堵代码墙的混乱道歉。扔掉,重新开始。任何会认真回答的人都必须这样做,所以你开始就好了。如果您发布的内容中有超过 10% 对您的问题有贡献,我会感到非常惊讶。扔掉剩下的 90% 将有助于我们和您将其固定下来。
  • 是的,我想我应该从这个重新开始...我想我想知道彼此内部的 forEach 循环......以及其中的承诺......以及异步和正在发生的事情同步发生了什么......但是我要重新开始......这是我早期编写的代码并且事情已经改变
  • 一般提示。取消嵌套您的代码。为每一个有意义的步骤编写专用函数。从分解最里面的东西开始。理想情况下,每个函数保持在四行代码以下。使用 map() 和 reduce()。链上你的承诺。倾向于运行一个 map() 多于少一个。无论如何,循环性能在异步情况下都不是您的问题,因此不要针对它进行优化。针对扁平、明显的代码进行优化。
  • 很酷,感谢您的建议...我决定在废弃代码之前再尝试一件事,它确实有效。我同意这段代码需要重构......遗憾的是,整个项目有点像这样对糟糕的项目管理造成没有时间赶上最后期限
  • 重构它以获得学习效果。学习对现实世界的场景(尤其是那些你已经熟悉的场景)更有效,而现实世界的场景比教科书的例子更有效。恕我直言,您无法获得更好的条件。 (我故意含糊其辞,我目前在移动设备上,无论如何现在都无法重构您的代码。我只是意识到已经超过了意大利面阈值并且重构到期了。)

标签: arrays angular typescript ionic-framework promise


【解决方案1】:

我在每个 forEach 循环中使用了一个承诺。我将所有的 Promise 推送到同一个 array 并使用了 Promise.all(array).then(...) 它在上面的使用方式 - 并且 Promise 完成了他们的工作 - 数组已排序,因为一切都是异步发生的。

【讨论】:

  • 大概.subscribe() 方法充当异步.get() 而不是真正的“订阅”。否则,即使在整理/修复之后,也很难看出上述方法会奏效。
猜你喜欢
  • 1970-01-01
  • 2016-08-11
  • 2019-11-26
  • 2019-04-13
  • 1970-01-01
  • 2019-06-13
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多