带有$ timeout的promise中的递归函数解析为快速

时间:2017-06-14 09:43:31

标签: angularjs typescript promise

我正在创建一个templateparser,它可以解析多个模板并返回生成的html内容。为了绑定html和视图信息,我使用的是Angular $compile服务。我遇到的问题是在解决promise之前调用了promise .then()(因此导致了undefined)。

AngularJS版本:1.6.3

解析器功能

/**
 * Using the $compile function, this function generates a full HTML page based on the given process and template
 * It does this by binding the given process to the template $scope and uses $compile to generate a HTML page
 * @param {Afhandeling} process - The process that can bind to the template
 * @param {string} templatePath - The location of the template that should be used
 * @param {boolean} [useCtrlCall=true] - Whether or not the process should be a sub part of a $ctrl object. If the template is used
 * for more then only an email template this could be the case (EXAMPLE: $ctrl.<process name>.timestamp)
 * @return {IPromise<string>} A full HTML page
 */
public createEmail(process: Afhandeling, templatePath: string, useCtrlCall = true): ng.IPromise<string> {
    let processScope = {};

    if (useCtrlCall) { //Create scope object | Most templates are called with $ctrl.<process name>
       const controller = "$ctrl";
       processScope[controller] = {};
       processScope[controller][process.__className.toLowerCase()] = process;
    } else {
       processScope = process;
    }

    return this.$http.get(templatePath)
        .then((response) => {
            let template = response.data;
            let scope = this.$rootScope.$new();
            angular.extend(scope, processScope);

            let generatedTemplate = this.$compile(jQuery(template))(scope);

            let waitForRenderCompletion = () => {
                if (scope.$$phase || this.$http.pendingRequests.length) {
                    console.warn("Time for a timeout.");
                    this.$timeout(waitForRenderCompletion);
                } else {
                    console.warn("Lets return the template.");
                    return generatedTemplate[0].innerHTML;
                }
            };
            waitForRenderCompletion();

      })
      .catch((exception) => {
          console.error(exception);
          this.logger.error(
             TemplateParser.getOnderdeel(process),
              "Email template creation",
              (<Error>exception).message
          );
          return null;
      });
}

函数调用

this.templateParser.createEmail(
    this.model,                
    "<template url>"
).then((template: string) => {
   console.warn(template); //Results in 'undefined'
});

我正在查看$$phase更改的原因是$compile没有就编译完成时提供任何反馈。模板可以由ng-include组合在一起的不确定数量的模板组成。 ng-includes也是异步,因此我无法想到检查$compile何时完成(My question about a better solution then this)的任何其他方法。

我在想什么

当我查看控制台输出时,我得到以下内容:

Time for a timeout.
undefined
(2) Time for a timeout.
Lets return the template.

因此,当第一个$timeout结算时,似乎会自动解决承诺。然而,这没有任何意义,因为我没有返回任何东西。

感谢任何帮助。

答案

感谢@charlietfl的提示。工作代码如下。我现在正在返回该函数,因此我的承诺中有一个返回值。我也返回$timeout,以便可以递归调用该函数。

代码:

let waitForRenderCompletion = () => {
   if (scope.$$phase || this.$http.pendingRequests.length) {
       console.warn("Time for a timeout.");
       return this.$timeout(waitForRenderCompletion);
       });
   } else {
       console.warn("Lets return the template.");
       return generatedTemplate[0].innerHTML;
   }
};
return waitForRenderCompletion();

0 个答案:

没有答案