首页 文章

AngularJS:链接承诺

提问于
浏览
2

根据AngularJS validation and promises的建议,我想链接确认对话框,从而立即验证几个步骤 .

基于用户提供的数据,进行API调用以查看用户需要确认的所有内容 . 对于需要确认的每个步骤,提示用户并让他们决定是否进入下一步 . 如果任何步骤返回false,则整个链应返回false .

我一直在阅读很多关于异步JS和承诺的内容,但我不得不承认我还是比较新的 . 如何正确链接这些以获得所有步骤的最终真/假?请注意,需要API调用来确定所有需要根据提供的信息向用户显示的内容,因此fetchSomeData()作为链中的第一个调用 .

任何帮助或建议将不胜感激 .

fetchSomeData = function() {
    var deferred = $q.defer();
    api.fetchData(param1, param2, param3)
        .then(function(data) {
        deferred.resolve(data.content);
    }, api.errorHandler);
    return deferred.promise;
}
// data = {condition1: false, condition2: true, condition3: true}
// display confirmation dialogs for step 2 and step 3, not step 1 

confirmStep1 = function(data) {
    if (data.condition1) {
        return confirmDialogService.popConfirm('step1').then(function(confirmed) {
            return confirmed;
        }, function() {
            return false;
        });
    } else {
        return $q.when(true);
    }
}

confirmStep2 = function(data) {
    if (data.condition2) {
        return confirmDialogService.popConfirm('step2').then(function(confirmed) {
            return confirmed;
        }, function() {
            return false;
        });
    } else {
        return $q.when(true);
    }
}

confirmStep3 = function(data) {
    if (data.condition3) {
        return confirmDialogService.popConfirm('step3').then(function(confirmed) {
            return confirmed;
        }, function() {
            return false;
        });
    } else {
        return $q.when(true);
    }
}

confirmSteps = function() {
    return fetchSomeData()
        .then(confirmStep1(data))
        .then(confirmStep2(data))
        .then(confirmStep3(data));
}

confirmSteps().then(function(allConfirmed) {
    if (allConfirmed == true) {
        doSomething();
    } else {
        return;
    }
});

1 回答

  • 1

    dfsq开始写一个答案,但删除了他的祝福,我正在添加我的看法:

    confirmSteps = function() {
        return fetchSomeData()
            .then(confirmStep1(data))
            .then(confirmStep2(data))
            .then(confirmStep3(data));
    }
    

    这调用函数,它与 setTimeout(alert("Hi"),5) 相同,你不想调用你想要链接它们的函数 . 喜欢 setTimeout(function(){ alert("Hi"); }, 5) ;

    confirmSteps = function() {
        return fetchSomeData()
            .then(confirmStep1)
            .then(confirmStep2)
            .then(confirmStep3);
    }
    

    但是,这会将 data 传递给第一个承诺,而前一个承诺的结果将传递给下一个承诺,而不是希望将 data 传递给所有三个承诺,您可以通过在一个级别上执行此操作:

    confirmSteps = function() {
        return fetchSomeData().then(function(data){
            var v1, v2;
            return confirmStep1(data).then(function(d){ 
               v1 = d;
               return confirmStep2(data);
            }).then(function(d){
               v2 = d;
               return confirmStep3(data);
            }).then(function(v3){
                return v1 && v2 && v3;
            })
        });
    };
    

    这是有效的,但它有点苛刻,相反,你可以使用短路 - 有点像 && 如果它是假的,只评估左手边 . 此外,我们可以在中心位置进行所有错误处理 . 这会使你的代码看起来像 .

    confirmStep1 = function(data) {
        if (data.condition1) return $q.when(true);
        return confirmDialogService.popConfirm('step1');
    };
    
    confirmStep2 = function(data) {
        if (data.condition2) return $q.when(true);
        return confirmDialogService.popConfirm('step2');
    };
    
    confirmStep3 = function(data) {
        if (data.condition3) return $q.when(true);
        return confirmDialogService.popConfirm('step3'):
    };
    
    confirmSteps = function() {
        var data = fetchSomeData();
        return data.then(confirmStep1).then(function(soFar){ 
             if(!soFar) return false; 
             return data.then(confirmStep2); 
        }).then(function(soFar){ 
             if(!soFar) return false; 
             return data.then(confirmStep3); 
        }).catch(function(){ return false; });
    };
    

    作为额外的提示:

    fetchSomeData = function() {
        var deferred = $q.defer();
        api.fetchData(param1, param2, param3)
            .then(function(data) {
            deferred.resolve(data.content);
        }, api.errorHandler);
        return deferred.promise;
    };
    

    可以简单地成为:

    fetchSomeData = function() {
        return api.fetchData(param1, param2, param3).then(function(data) {
            return data.content;
        }, api.errorHandler);
    };
    

相关问题