【问题标题】:Angular wait for promise to resolve before proceedingAngular 在继续之前等待承诺解决
【发布时间】:2018-12-14 14:00:21
【问题描述】:

我的以下代码是项目验证部分的一部分。这段代码的目的是检查引用表中是否存在值。如果确实存在,则可以继续。如果不是,则抛出错误并停止用户。

saveChanges() {
    //blah blah
    if (needTovalidate){
    passedCheck = false;
    this.validationService.checkExistence(value)
    .then((exist: boolean) => {
      passedCheck = exist;
      console.log("INSIDE: " + exist);

    });
    console.log("OUTSIDE: " + passedCheck);

    if(passedCheck) {
        //Rest of code
    } else {
        //Throw error msg
    }
}


public async checkExistence(value: string): Promise<boolean>{
  var exist = false;
  return this.getRefData().then((rec: dataModel[]) => {
    return rec.some(el => {
      return el.col1 === value;
    });
  });
}

private async getRefData() {
  return await this.configurationService.retrieveTableData().toPromise(); 
}

预期日志:

INSIDE: true
OUTSIDE:true

实际日志:

OUTSIDE: false
INSIDE: true

显然,代码在继续下一行之前没有等待布尔诺言解决。

有什么建议吗?

【问题讨论】:

  • 将其余代码放在.then() 处理程序中。这是诺言中的布尔值唯一有效的地方。这是一个异步操作。 .then() 处理程序在未来某个不确定的时间被调用。 .then() 处理程序之后的其余函数在promise 完成之前和.then() 处理程序被调用之前执行。因此,唯一使用 promise 结果的地方是在 .then() 处理程序中。这里可能有超过 1000 个此类问题的其他示例,所以如果您想搜索的话,会有很多重复。
  • 谢谢@jfriend00 我也看过很多帖子,但不确定我的情况是否有所不同...谢谢。
  • 没有什么不同。将在异步回调中获得的值分配给更高范围的变量,以便您可以“希望”在其他地方使用它,这在 node.js 中几乎总是一个错误。这是一个明显的警告信号,表明你做错了。在回调中使用您获取它的值或将其传递给您从该回调中调用的另一个函数。这就是你在 node.js 中编写异步代码的方式。
  • 另外return await xxxx() 是一种浪费。只需执行return xxxx()。他们都返回了一个承诺,该承诺将以适当的价值解决。您必须在返回的 Promise 上使用 .then() 才能获取值。

标签: angular promise


【解决方案1】:

正如@jfriend00 在您的评论讨论中提到的那样,这是对类似问题的欺骗,无论何时使用异步函数(Promise、Observable),您都应该将异步性冒泡回调用和.then 或@987654327 @那里。

Return value with asynchronous functions in Typescript

有什么建议吗?

您可以通过与此类似的方式更改您的 saveChanges 和 checkExistence 函数:

请参阅下面的示例并可能在编辑中清理您的问题示例代码(如果不重写以制作更好的示例问题,我相信您至少可以通过花时间自己解决您的问题再费力地复习一遍)

您提供的伪代码存在一些问题,但我尝试尽可能地概念化该过程,同时保持对您的原始代码的真实性。

saveChanges(needToValidate: boolean, // ??
  changesToValidate: Changes,
  asyncValidateFunction: (changes: Changes) => Promise < boolean > , // hmm
) {

  asyncValidateFunction(changesToValidate);
  //blah blah
  if (needToValidate) { // Random context here? Feels like too many things going on in one. Try to isolate functionality.
    this.validationService.checkExistence(value)
      .then(
        (exist: boolean) => {
          yourStuffToDoAfterPassedCheckValidation(exist) // hmm
          console.log("INSIDE: " + exist); // be safe and stay inside :)
        }
      );

  }
}

// Tried to encapsulate as much as your original concept and style from original question. 
// Please refactor this based on your understanding
yourStuffToDoAfterPassedCheckValidation(passedCheckFlag: boolean) {
  if (passedCheckFlag) {
    // Rest of code
  } else {
    // Throw error msg
  }
}

public checkExistence(value: string): Promise < boolean > {
  // Unused junk code? var exist = false;

  return this.getRefData()
    .then(
      (rec: dataModel[]) => {
        return rec
          .some(el => {
            return el.col1 === value;
          });
      });
}

由于这是在 Angular 中,这可能与 Angular 表单有关吗? Async validators might be helpful to you even if not directly related

与Return value with asynchronous functions in Typescript 和其他许多类似的问题 我在这些类型的问题中发现了类似的不一致,可以通过明确输入 TypeScript 来改进,以提供更快的反馈以防止出现问题!

如果您需要更具体的帮助,请提供原始代码的重构版本,因为有些东西似乎被弱替换了。

否则,我们可以更清晰地处理伪代码。 由于这似乎是一个重复的问题,会产生类似的异步错误,因此您可以提供代码不起作用的上下文,否则其他问题中已经提供了全面的答案?。

在对纠结的代码进行故障排除时,它可能会帮助您先将整个程序流程重写为伪代码,然后基于此重新生成代码以巩固您想要理解的内容。 (这就是为什么我有时建议您手写您的程序,或者至少将所有内容分解为分配的变量,明确键入所有内容并尽可能多地使用TypeScript语言服务。

编辑:我看到您已经重复了您自己的问题,这个问题更加清晰,并且正在努力解决您的问题。我希望你只是在一个地方更新你的问题。从您其他问题中的 cmets 来看,您似乎不想遵循 Promise 的基本异步用法的建议,并且仍然希望依赖尚不存在的变异值(异步)。

【讨论】:

  • 我的评论可能有点苛刻。你是响应式编程的新手,我建议你先学习几个使用 Promises 的小教程来感受它。还要对Observables感到满意,因为我认为您可能会遇到更多问题,具体取决于您的服务,并且尝试承诺一切可能会使它变得更加复杂。 (偏爱)。在这些教程上花几个小时,而不是在 Stack Overflow 上正确格式化 QA,可能对你来说学习效率更高。
【解决方案2】:

我使用的最简单的方法是创建一个布尔变量并在then 和catch 中将其设为假

例子:

let isPromisePending = false;

function someFn() {
  isPromisePending = true;
  myPromise().then(() => {
    isPromisePending = false;
    //Success handler below
  }).catch(() => {
    isPromisePending = false;
    //Error handler below
  })
}

【讨论】:

    猜你喜欢
    • 2017-07-31
    • 1970-01-01
    • 2021-08-11
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    相关资源
    最近更新 更多