AngularJS:链接的承诺 [英] AngularJS : Chaining promises

查看:125
本文介绍了AngularJS:链接的承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AngularJS确认和承诺的建议,我想链确认对话框和从而使在一次几个步骤。

基于由用户提供的数据

,的API调用,以查看所有需要的东西由用户进行确认。
对于需要确认每一个步骤,提示用户,让他们决定是否进入下一步骤。
如果任何一步返回false,整个产业链应返回false。

我已经读了很多关于异步JS和承诺,但我不得不承认,我还是相当新的吧。
如何妥善链中获得最终的真/假所有步骤?注意,API调用是需要的确定所有需要显示根据提供的信息的用户什么,因此fetchSomeData(),为在链中第一个呼叫。

任何帮助或建议,将大大AP preciated。

  fetchSomeData =功能(){
    变种推迟= $ q.defer();
    api.fetchData(参数1,参数2,参数3)
        。然后(功能(数据){
        deferred.resolve(data.content);
    },api.errorHandler);
    返回deferred.promise;
}
//数据= {条件1:假的,条件2:真实,condition3:真正}
//显示确认对话框步骤2和步骤3,而不是1步confirmStep1 =功能(数据){
    如果(data.condition1){
        返回confirmDialogService.popConfirm('第一步'),然后(功能(确认){
            返回确认;
        },函数(){
            返回false;
        });
    }其他{
        返回$ q.when(真);
    }
}confirmStep2 =功能(数据){
    如果(data.condition2){
        返回confirmDialogService.popConfirm('第二步'),然后(功能(确认){
            返回确认;
        },函数(){
            返回false;
        });
    }其他{
        返回$ q.when(真);
    }
}confirmStep3 =功能(数据){
    如果(data.condition3){
        返回confirmDialogService.popConfirm('步骤3'),然后(功能(确认){
            返回确认;
        },函数(){
            返回false;
        });
    }其他{
        返回$ q.when(真);
    }
}confirmSteps =功能(){
    返回fetchSomeData()
        。然后(confirmStep1(数据))
        。然后(confirmStep2(数据))
        。然后(confirmStep3(数据));
}confirmSteps()。然后(功能(allConfirmed){
    如果(allConfirmed ==真){
        做一点事();
    }其他{
        返回;
    }
});


解决方案

dfsq开始写一个答案,但以他的祝福我加入我拿上它删掉了他这样:

  confirmSteps =功能(){
    返回fetchSomeData()
        。然后(confirmStep1(数据))
        。然后(confirmStep2(数据))
        。然后(confirmStep3(数据));
}

这个调用的函数,这是一样的的setTimeout(警报(你好),5)你不想给你打电话要的功能把它们连。像的setTimeout(函数(){警报(你好);},5);

  confirmSteps =功能(){
    返回fetchSomeData()
        。然后(confirmStep1)
        。然后(confirmStep2)
        。然后(confirmStep3);
}

不过,这会通过数据来只有第一个承诺和previous承诺到下一个结果,而不是你想传递数据所有三个,你可以通过neting一级做到这一点:

  confirmSteps =功能(){
    返回fetchSomeData()。然后(功能(数据){
        VAR V1,V2;
        返回confirmStep1(数据)。然后(函数(D){
           V1 = D;
           返回confirmStep2(数据);
        })。然后(函数(D){
           V2 = D;
           返回confirmStep3(数据);
        })。然后(功能(V3){
            返回V1和放大器;&安培; v2和放大器;&安培; V3;
        })
    });
};

这工作,但它是一种这些混沌,而是可以用短路 - 有点像如何&放大器;&安培; 只有当它的falsey评估左手边。此外,我们可以做所有的错误在一个中心位置处理。这将使您的code样子。

  confirmStep1 =功能(数据){
    如果(data.condition1)返回$ q.when(真);
    返回confirmDialogService.popConfirm('第一步');
};confirmStep2 =功能(数据){
    如果(data.condition2)返回$ q.when(真);
    返回confirmDialogService.popConfirm('第二步');
};confirmStep3 =功能(数据){
    如果(data.condition3)返回$ q.when(真);
    返回confirmDialogService.popConfirm('步骤3'):
};confirmSteps =功能(){
    VAR数据= fetchSomeData();
    返回data.then(confirmStep1)。然后(功能(SOFAR){
         如果返回false(SOFAR!);
         返回data.then(confirmStep2);
    }),然后(功能(SOFAR){
         如果返回false(SOFAR!);
         返回data.then(confirmStep3);
    })赶上(函数(){返回false;});
};

作为一个额外的提示是:

  fetchSomeData =功能(){
    变种推迟= $ q.defer();
    api.fetchData(参数1,参数2,参数3)
        。然后(功能(数据){
        deferred.resolve(data.content);
    },api.errorHandler);
    返回deferred.promise;
};

能否简直成了:

  fetchSomeData =功能(){
    返回api.fetchData(参数1,参数2,参数3)。然后(功能(数据){
        返回data.content;
    },api.errorHandler);
};

Following the suggestions from AngularJS validation and promises, I would like to chain confirmation dialogs and thus validate several steps at once.

Based on data provided by the user, an API call is made to see what all needs to be confirmed by the user. For each step that needs confirmation, prompt the user and let them decide whether to go to next step. If any step returns false, the whole chain should return false.

I've been reading a lot about async JS and promises, but I have to admit I am still fairly new to it. How to properly chain these to get a final true/false for all steps? Note that an API call is needed to determine what all needs to be shown to the user based on provided information, hence fetchSomeData() as first call in the chain.

Any help or suggestions will be greatly appreciated.

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;
    }
});

解决方案

dfsq started writing an answer but deleted his so with his blessing I'm adding my take on it:

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

This calls functions, it's the same as setTimeout(alert("Hi"),5) you don't want to be calling the functions you want to chain them. Like setTimeout(function(){ alert("Hi"); }, 5);

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

However, that would pass data to the first promise only and the result of the previous promise to the next one, instead you want to pass data to all three, you can do this by neting one level:

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;
        })
    });
};

This works but it's kind of crufty, instead you can use short circuiting - kind of like how && only evaluates the left hand side if it's falsey. Moreover we can do all error handling in a central location. This would make your code look like.

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; });
};

As an extra tip this:

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

Can simply become:

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

这篇关于AngularJS:链接的承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆