由Promise混合同步和异步。然后无法正常运行

时间:2019-07-10 23:35:06

标签: javascript node.js angular typescript

这是我的代码:

private loadingData() {
   var promise = new Promise<any>((resolve) => 
   {
       resolve();
   });
   promise.then(() => {
       this.asyncServiceCall();
   })
   .then(() => this.syncFunctionThree())
};

异步方法asyncServiceCall实际上返回一个Promise。

private asyncServiceCall(): Promise<any> {
    return new Promise((resolve) = > {
        resolve();
    }).then(() => {
       this.functionOne()
       })
      .then(() => {
       this.functionTwo();
    });
}

好的,让我们看一下functionOnefunctionTwo。他们俩都返回了Promise。

private functionOne() {
   return new Promise((resolve) => {
    this.user['load'] = true;
    this.service['user'].get().subscribe(d => 
  {
     this.user['d'] = d;
  },
  error => console.error(error),
  () => {
     this.role['load']=false;
   });
  resolve();
});
}

private functionTwo() {
   return new Promise((resolve) => {
    this.service['name'].get().subscribe(d => 
  {
     this.name['d'] = d;
  },
  resolve();
});
}

第三种方法syncFunctionThree将使用数据this.user['d']this.name['d']来具有一些业务逻辑。所以我想先打电话给functionOnefunctionTwo,然后再打电话给syncFunctionThree

通过the accepted answer without creating new Promise,我并不幸运。我发现 syncFunctionThree在异步方法之前被调用。

所以请帮助我。

2 个答案:

答案 0 :(得分:1)

您错过了在then()内调用诺言的重要部分...您需要return那些诺言,否则then()将立即解决并转到下一个then()连锁,链条。这就是为什么functionThree在异步promise函数解析之前触发

private loadingData() {
   var promise = new Promise<any>((resolve) => 
   {
       resolve();
   });
   promise.then(() => {
      // return the promise this function returns
      return this.asyncServiceCall();
     // ^^^^
   })
    // this then() won't fire until asyncServiceCall resolves in previous then()
   .then((resultFromPriorThen) => this.syncFunctionThree())
}

现在您真的不需要loadingData()中的第一个诺言,因为您已经有了asyncServiceCall()返回的诺言,可以简化为:

private loadingData(): Promise<any> {      
   return this.asyncServiceCall().then(()=>this.syncFunctionThree());
}

现在以相同的方式修复asyncServiceCall()

private asyncServiceCall(): Promise<any> {   
   return this.functionOne().then(()=>this.functionTwo());   
}

最后说明:如果其中一个异步操作有问题,则需要在catch()中添加loadingData()

答案 1 :(得分:1)

private functionOne() {
   return new Promise((resolve) => {
    this.service['user'].get().subscribe(resolve);
  });
}

private functionTwo() {
   return new Promise((resolve) => {
    this.service['name'].get().subscribe(resolve);
  });
}

private loadingData() {
   Promise.all([functionOne(), functionTwo()]).then(([user, name]) => {
      this.user['d'] = user;
      this.name['d'] = name;
   }).then(() => this.syncFunctionThree())
};

如果this.service['user'].get()是可观察的rx,则通过查看方法签名。您可以使用this.service['user'].get().toPromise()直接获得承诺。如果this.service['user'].get()有多个值,请尝试使用this.service['user'].get().pipe(first())