Angular Promise.all在超时事件中不起作用

时间:2018-11-26 07:30:36

标签: javascript angular typescript

我在使用Angular 6时遇到以下问题。我试图做的是等待一些诺言被解决,然后再做其他事情。这是我所拥有的并且正在运行:

AppService.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AppService {

  p1: Promise<any>;
  p2: Promise<any>;

  constructor() { 
    this.getPromise1();
    this.getPromise2();
  }

  getPromise1() {
    this.p1 = new Promise((resolve, reject) => {
      resolve(true);
    });
  }

  getPromise2() {
    this.p2 = new Promise((resolve, reject) => {
      setTimeout(() => resolve(true), 5000);
    });
  }
}

AppComponent.ts

import { Component, AfterViewInit } from '@angular/core';
import { AppService } from './app.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent  implements AfterViewInit {

  constructor(private appSrvc: AppService) { }

  ngAfterViewInit(){
    Promise.all([this.appSrvc.p1, this.appSrvc.p2])
      .then(values => { 
          console.log(values);
          //If all promises resolved then execute something here
      })
      .catch(error => { 
          console.log(error.message)
      });
  }
}

现在,当我编辑以下内容时,它不起作用:

AppService.ts

 constructor() { 
    this.initialize();
  }

  initialize(){
    setTimeout(() => {
      this.getPromise1();
      this.getPromise2();
    }, 1000);
  }
  ...

当我通过超时事件从另一个方法调用相同的promise时,它们将不起作用,我也无法理解为什么。谁能帮我这个忙。

预先感谢

1 个答案:

答案 0 :(得分:1)

会发生什么:

  1. AppService构造函数在注入模块时被调用
  2. 注入AppComponent后几毫秒
  3. 大约100毫秒后AppComponent=>ngAfterViewInit()被呼叫

设置超时时,这两个Promise的初始化被推迟1000ms。到那时,您的AppComponent=>ngAfterViewInit()已经完成,这两个将要承诺的价值实际上是undefined。要解决此问题,您需要同步这两个事件,因此可以从AppService.initialize()调用AppComponent来解决问题,但还必须使其异步。

以下是您如何同步此示例:

getPromise1() {
    if(!this.p1) {
        return this.p1 = new Promise((resolve, reject) => {
            resolve(true);
        });
    }
    return this.p1;
}
getPromise2() {
    if(!this.p2) {
        return this.p2 = new Promise((resolve, reject) => {
          setTimeout(() => resolve(true), 5000);
        });
    }
    return this.p2;
}

然后在呼叫站点:

ngAfterViewInit(){
    Promise.all([this.appSrvc.getPromise1(), this.appSrvc.getPromise2()])
        .then(values => { 
                console.log(values);
                //If all promises resolved then execute something here
        })
        .catch(error => { 
                console.log(error.message)
        });
}