javascript - from - AngularJS: encadenando promesas
promesa angular js (1)
dfsq comenzó a escribir una respuesta, pero eliminó la suya, así que con su bendición voy a agregar mi opinión:
confirmSteps = function() {
return fetchSomeData()
.then(confirmStep1(data))
.then(confirmStep2(data))
.then(confirmStep3(data));
}
Esto llama a funciones, es lo mismo que setTimeout(alert("Hi"),5)
no desea llamar a las funciones que desea encadenar. Como setTimeout(function(){ alert("Hi"); }, 5)
;
confirmSteps = function() {
return fetchSomeData()
.then(confirmStep1)
.then(confirmStep2)
.then(confirmStep3);
}
Sin embargo, eso pasaría los data
a la primera promesa solamente y el resultado de la promesa anterior a la siguiente, en su lugar, desea pasar los data
a los tres, puede hacerlo al netear un nivel:
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;
})
});
};
Esto funciona, pero es un poco complicado, en su lugar se puede usar un cortocircuito, como cuando &&
solo evalúa el lado izquierdo si es falsey. Además, podemos hacer todo el manejo de errores en una ubicación central. Esto haría que tu código se vea como
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; });
};
Como consejo adicional, esto:
fetchSomeData = function() {
var deferred = $q.defer();
api.fetchData(param1, param2, param3)
.then(function(data) {
deferred.resolve(data.content);
}, api.errorHandler);
return deferred.promise;
};
Simplemente puede convertirse en:
fetchSomeData = function() {
return api.fetchData(param1, param2, param3).then(function(data) {
return data.content;
}, api.errorHandler);
};
Siguiendo las sugerencias de validación y promesas de AngularJS , me gustaría encadenar diálogos de confirmación y así validar varios pasos a la vez.
Según los datos proporcionados por el usuario, se realiza una llamada API para ver qué necesita confirmar el usuario. Para cada paso que necesita confirmación, solicite al usuario y déjelos decidir si pasar al siguiente paso. Si cualquier paso devuelve falso, toda la cadena debería devolver falso.
He estado leyendo mucho sobre la asincronización de JS y las promesas, pero debo admitir que aún soy bastante nuevo. ¿Cómo encadenarlos adecuadamente para obtener un verdadero / falso final para todos los pasos? Tenga en cuenta que se necesita una llamada API para determinar qué debe mostrarse al usuario en base a la información proporcionada, por lo tanto fetchSomeData () como primera llamada en la cadena.
Cualquier ayuda o sugerencia será muy apreciada.
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;
}
});