来自promise的等待功能

时间:2019-10-31 18:02:43

标签: typescript promise

我尝试从.then()调用以下功能

   public waitFunction(): any {
        setTimeout(function() {
            this.getMap1();
        }, 1000);
        return;
    }

    public getMap1(): any {
        this.autoSchemaRecords = null;
        this._clientFileMappingService.getAllById(this._clientFileId).subscribe(
            r => {
                this.autoSchemaRecords = r;
            },
            e => {
                this.showLoader = false;
                throw e;
            },
            () => {
                this.showLoader = false;
            }
        );
        return;
    }

当我尝试从下面的waitFunction()调用.then()时,出现以下错误:

  

this.getMap1不是函数

const result = this._clientFileMappingService
    .fileUpload(autoSchema, this._clientFileId)
    .then(this.hideModal(), this.waitFunction())
    .catch(err => {
        throw err;
    });

这让我感到困惑,因为除了服务之外的所有东西都在同一个组件中。

出于各种原因,我目前在.fileUpload方法中使用了Promise。如果该功能是可观察到的,我认为我不会遇到这个问题。但是,我目前无法更改。

有人可以引导我朝正确的方向等待1秒以重新填充autoSchemeaRecords集合吗?

2 个答案:

答案 0 :(得分:1)

专门为解决此类问题而在语言中添加了“箭头语法”或一些称其为“脂肪箭头语法”的声明函数。

对使用常规函数语法(无粗体箭头语法)定义的函数的所有函数调用都会根据函数的调用方式来设置新值this。您可以在The six ways to control the value of this in a function call上看到设置或控制this的各种方式。

因此,您对setTimeout()进行的回调将在该回调中引起this的不同值。在这种情况下,它将是global值或undefined(如果在严格模式下运行),因为当setTimeout()调用回调时,它将“重置”为默认值。

假设waitFunction()是一种本身具有正确的this(这是您的代码显示的方法)的方法,其调用方式类似于obj.waitFunction()this.waitFunction(),那么您可以切换到粗箭头功能,它将保留this的词法值,而不是设置一个新值:

public waitFunction(): any {
    setTimeout(() => {
         // will have the same value of this that was
         // present before the setTimeout() was executed
         // which is what you want
         this.getMap1();
    }, 1000);
    return;
}

或者,一个更紧凑的版本(单条语句箭头功能可以跳过花括号):

public waitFunction(): any {
    setTimeout(() => this.getMap1(), 1000);
}

代码运行时,this的词法值自然是this函数调用之前setTimeout()的值。在这种情况下,该值是您要在回调内部获得的值,因此胖箭头语法非常适合这种情况,因为它保留了所需的this的值。

因此,粗箭头语法基本上是两件事:

  1. 较短的函数声明语法
  2. 在函数内部保留this的词法值的一种方法

当您想保留this的值时,它们非常适合于内联函数声明

您可以了解有关here on MDN的更多信息。


此外,请记住,waitFunction()最好命名为delayFunction(),因为它实际上并不“等待”任何东西。 setTimeout()是非阻塞的。延迟后它将调用this.getMap1(),但它将立即返回,并且其他代码将继续运行。因此,这并不是真正的“等待”。只是想确保您对此不感到困惑。

答案 1 :(得分:0)

setTimeout 来自香草JS,所以根据您的代码

   public waitFunction(): any {
    let context=this;
    setTimeout(function() {
        context.getMap1();
    }, 1000);
    return;
}

public getMap1(): any {
    this.autoSchemaRecords = null;
    this._clientFileMappingService.getAllById(this._clientFileId).subscribe(
        r => {
            this.autoSchemaRecords = r;
        },
        e => {
            this.showLoader = false;
            throw e;
        },
        () => {
            this.showLoader = false;
        }
    );
    return;
}

为便于理解,请将上下文作为变量传递,否则setTimeout将尝试从JS环境中找到上下文。