AngularJS:Promises&基于结果的条件

时间:2014-04-11 12:21:11

标签: angularjs promise angularjs-resource

我有一个复杂的承诺链,每个成功处理程序然后进行更多的API调用并将结果传递给下一个,依此类推。

我的情况是,根据情况,我可能会选择停止连锁。

因此,简而言之,我的代码看起来像;

API.callGeneric(/* some params here */)
    .$promise
    .then(success(res) {
        if (processFurther(res)) {
            return API.callGeneric(res).$promise;
        } else {
            return someFunction(res); // so that the stuff inside the next successhandler still happens
        }
    }, failHandler)
    .then(success(res) {
        // do some stuff with res
        // do some important stuff independent of res (announce app ready, etc.)
    }, failHandler)

因此,无论我是否选择从另一个API调用或仅仅是一个对象返回promise,都需要在最后一步中发生一些事情。

怎么办呢?

2 个答案:

答案 0 :(得分:2)

@BenjaminGruenbaum的帮助下解决了这个问题。

所以,基本上,我需要最后一个.then的successHandler来执行 - 至少它的一部分并不依赖于链中早先传递的承诺。

解决这个问题的方法是使用.finally,但有一个问题。无论您决定拒绝承诺并打破链条,.finally都会执行。在我的场景中,这不是我需要的。在.finally中,我需要宣布我的webapp已准备好(通过websocket)到服务器和其他客户端。但如果第一个API调用本身必须被拒绝,那就不太理想了。

解决这个问题的方法是通过承诺链保持一定程度的进度,以便finally中的处理程序完全了解已经取得了多大进展。如果这超出了我的应用程序宣布准备的某个限制,我忽略了最后的承诺拒绝。

所以基本上,解决方案现在看起来像这样;

var progress = 0;
API.callGeneric(/* some params */).$promise

    .then(successOne(res) {
        progress++;
        return API.callGeneric(res).$promise;
    }, handleErr)

    .then(successTwo(res) {
        progress++;
        if (isResPositive(res)) {
            return API.callGeneric(res).$promise;
        } else {
            var def = $q.defer();
            def.reject(res);
            return def.promise;
        }
    }, handleErr)

    .then(/* similar stuff */)

    /* etc */

    .finally(function () {
        if (progress > limit) {
            // do stuff here
        } else {
            // failure, don't do stuff
        }
    });

答案 1 :(得分:0)

您可以使用拒绝承诺(如$q.reject(reason)作为函数的返回值。

.then(function () { 
   return $q.reject() 
}).then(function () {
  console.log('never happens'); 
}).catch(function () { 
  console.log('you are going here because of the reject above'); 
}).finally(function () {
  console.log('always happens');
});

请查看the documentation以获取更多信息。