2015-12-02 65 views
0

注:这是打字稿/角的1.4.x链接AngularJS控制器中的承诺。此解决方法是否有效?

Plunker在javascript:http://plnkr.co/edit/LCka4CFLcRe0lPEF9AM2?p=preview

我不得不链多次调用与承诺。 init3取决于init2取决于init1

一些承诺即使失败也需要继续。所以我不得不在这里使用扁平化技术:http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/重用回调代码。

问题是,当链接的承诺,我完全失去第一个链,然后(init2init3)内部控制的this例如 所以我修改内部收益通过控制器链使绑定(绑定到控制器)和服务是可访问的。

这是有效/正确吗? (通过链中的控制器并重复使用相同的回调来获得成功/错误)

代码中的注释也解释/提出问题。

代码:

export class ControllerX { 

    private myInformation: string; 
    private myMoreInformation: string; 

    public constructor(private $q: ng.IQService, private service1: Service1) { 

     this.init() 
      .then(this.init2) //If init() fails dont continue the chain 
      .then(this.init3, this.init3); //Even if init2() fail, we continue. 
      //init2() cannot fail now but its a recovery example. 
    } 

    private init(): ng.IPromise<ControllerX> { 
     return this.service1.getMyInformation().then((information: string): ControllerX => { 
      this.myInformation = information; 
      return this; //Push this for the next then 
     }); //Do nothing on error, let it propagate. 
    } 

    private init2(ctrl?: ControllerX): ng.IPromise<ControllerX> { 

     if (!ctrl) { //Are we called from a chain 
      ctrl = this; 
     } 

     return ctrl.service1.getMyMoreInfo().then((information: string): ControllerX => { 
      ctrl.myMoreInformation = information; 
      return ctrl; 
     }, (error: any): ControleurListeCours => { 
      ctrl.myMoreInformation = DEFAULT; 
      return ctrl; 
     }); 
    } 

    private init3(ctrl?: ControllerX): ng.IPromise<ControllerX> { 
     //blablabla 
    } 
} 
+0

我的情况有所不同。第一次调用init()实际上是一个等价的胖箭头。这是完美的工作。然后我在第二次放松“这个”。 (链接的一个,init2和init3)这就是为什么我必须开始在链式承诺中返回控制器作为参数。 – Rouche

+0

我返回“this”,因此init2可以接收控制器作为参数。 (承诺链)我没有找到任何其他方式来访问init2中的控制器。 – Rouche

回答

0

预期该代码将无法正常工作。

this.init() 
     .then(this.init2) //If init() fails dont continue the chain 
     .then(this.init3, this.init3); //Even if init2() fail, we continue. 
     //init2() cannot fail now but its a recovery example. 

如果init失败,代码将跳过init2但将被第二then方法被捕获,并且init3将被执行。

HTML

<div ng-app="myApp" ng-controller="myVm as vm"> 
    <pre> 
init1 status = {{vm.init1Status}} 
init2 status = {{vm.init2Status}} 
init3 status = {{vm.init3Status}} 
    </pre> 
</div> 

JS

angular.module('myApp',[]).controller('myVm', function ($q) { 
    var vm = this; 
    vm.init1Status = "not done"; 
    vm.init2Status = "not done"; 
    vm.init3Status = "not done"; 

    function init1() { 
     vm.init1Status = "init1 failed"; 
     return $q.reject("init1 failed"); 
    }; 

    function init2() { 
     vm.init2Status = "init2 done"; 
    }; 

    function init3() { 
     vm.init3Status = "init3 done"; 
    }; 

    init1().then(init2).then(init3,init3); 
}); 

结果

init1 status = init1 failed 
init2 status = not done 
init3 status = init3 done 

JSFiddle

+0

@georgeawd嗨,谢谢你的回答。我做了一些测试,看到了这个问题。所以我修改我的情况,所以当我想停止链条时,我返回一个拒绝。现在它看起来更像这样,但最初的想法仍然有效并且正在工作:'init1()。then(init2,stop).then(init3,stop).then(stop);函数停止(ctrl){ctrl.loading = false; $ q.reject(); }' – Rouche

+0

@georgeawd我也看到在纯JS中,你没有我在TypeScript中遇到的问题。我在plunker上的版本是从TypeScript编译生成的JavaScript。如果你调试了,你会在init2里看到上下文丢失了。修改小提琴以更好地管理链条。 :[链接](http:// jsfiddle。net/mmp7923s/7 /) – Rouche

+0

有时Plnkr已关闭,因此这是[Fiddle](http://jsfiddle.net/mmp7923s/13/)中的TypeScript编译版本。控制台显示“这个”问题。 – Rouche