【问题标题】:Access outer variable inside Angular Promise then() function在 Angular Promise then() 函数中访问外部变量
【发布时间】:2017-08-06 06:51:18
【问题描述】:

大家晚上好。我想知道如何在 Angular 2/4 的打字稿中访问 Promise 的 then() 中的外部变量。我正在尝试完成动态表单验证,以通过 Rest API 检查用户名可用性。

这里userService.isUsernameAvailable(userName) 返回一个完美运行的承诺。我唯一想要回答的是,如何更改 then()catch() 上的 i 值。

static usernameAvailabilityValidator(userService: UserService) {
      let i = 1; //outer variable
      userService.isUsernameAvailable(userName).then((res) => {
        i = 2;
      }).catch((res) => {
        i = 3;
      });
      console.log("i is "+ i); // should output 2 or 3
  }

以下无关

以下与此问题无关:我在下面添加代码以提供我要实现的目标的上下文。您不必阅读它,它不会增加我的问题。

我的目标是返回一个函数,该函数返回 null 或验证器的 JSON 对象,因为这就是验证器在 Angular 2 中的工作方式。

static usernameAvailabilityValidator(userService: UserService) {
    return (control: FormControl) : any =>{
      let userName: string = control.value;
      console.log("current username"+userName);
      let i = 1;
      let response:{} = null; //here response is similar to i
      userService.isUsernameAvailable(userName).then((res) => {
        i++;
        if (res.status == 1) {
          response = null;
        }
        else {
          response = {'usernameInUse': 1};
        }

      }).catch((res) => {
        response = null;
      });
      console.log("i"+i);
      return response; // response is returned to the outside function
    }
  }

提前谢谢大家。

【问题讨论】:

标签: javascript angular typescript angular-promise


【解决方案1】:

isUsernameAvailable 返回一个 Promise,因为它不能在被调用后立即返回一个值(因为它例如等待网络请求)。因此,您的 console.log("i"+i);return response; 在您的 then 回调之前和变量被修改之前被调用。因此,您的 usernameAvailabilityValidator 无法立即返回值,您可以改为返回 Promise 或使用 TypeScript 的 async/await 功能 (https://basarat.gitbooks.io/typescript/content/docs/async-await.html)。

【讨论】:

    【解决方案2】:

    您需要实现相同的异步验证器

    例如 -

    validate(c:AbstractControl) {
        return new Promise(resolve =>
          this.accountService.getUserNames(c.value).subscribe(res => {
            if (res == true) {
                resolve(null);
            }
            else {
                resolve({validateEmailTaken: {valid: false}});
            }
        }));
      }
    

    您可以在 ReactiveTemplateDriven 上找到有关验证器的更多信息

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 2018-05-13
      • 1970-01-01
      • 2015-02-20
      • 2017-05-25
      • 2014-01-29
      • 1970-01-01
      相关资源
      最近更新 更多