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

标签 javascript angular typescript

我在使用 Angular 6 时遇到以下问题。我想做的是等待一些 promise 得到解决,以便做其他事情。这是我所拥有的并且正在运行:

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. AppService 构造函数在注入(inject)模块时被调用
  2. 注入(inject) AppComponent 几毫秒后
  3. 大约 100 毫秒后,AppComponent=>ngAfterViewInit() 被调用

当你设置超时时,这两个promise的初始化会推迟1000ms。此时,您的 AppComponent=>ngAfterViewInit() 已经完成,这两个 future promise 的值实际上是 未定义。要解决此问题,您需要同步这两个事件,因此从 AppComponent 调用 AppService.initialize() 即可解决问题,但您还必须使其异步。

以下是如何同步的示例:

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)
        });
}

关于javascript - Angular Promise.all 在超时事件中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53476482/

相关文章:

javascript - ngClass 在 Angular 4 中不起作用

javascript - 在 Angular 中选中/取消选中复选框时如何调用不同的方法?

css - Angular - 列表元素的交错动画

typescript - 根据子尺寸设置父尺寸的高度和宽度

javascript - 如何将多个属性键作为参数传递给使用括号表示法的函数?

javascript - postMessage 期间 Microsoft Edge 中的 SCRIPT5022 语法错误

javascript - 如何在 Node 控制台中记录深度嵌套的对象

带有全选选项的 Angular Material 多选下拉列表

javascript - TypeScript 的目的是像 JavaScript 那样用于操纵 DOM 吗?

javascript - 导出数据和固定数据表