AngularJS 承诺链接 $q.all 的最佳实践
AngularJS Promise best practise for chaining $q.all
我是编写和使用 promises 的新手,我需要一些建议。我必须遵守我的承诺,因为有些功能只能在其他功能之后 运行。我曾经用很多回调函数来处理这个问题,看起来非常混乱和混乱。但是随着我正在做的链接……它又开始看起来有点乱了,我想知道我这样做是否正确……
function calcNetPriceSaleCharge(theItem) {
var setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem);
var setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
$q
.all([setInitialChargeAmount, setDiscountAmount])
.then(function(values) {
theItem.initialchargeamount = values[0];
theItem.initialdiscountamount = values[1];
})
.then(function() {
var setActualCharge = miscSaleSvc.getActualCharge(theItem);
var setVat = miscSaleSvc.setVat(theItem);
$q
.all([setActualCharge, setVat])
.then(function(values) {
theItem.actualcharge = values[0];
theItem.vat = values[1];
})
.then(function() {
var setTotal = miscSaleSvc.getSaleTotal(theItem);
$q
.all([setTotal])
.then(function(values) {
theItem.total = values[0];
})
.catch(function(error) {
console.log(error);
});
})
.catch(function(error) {
console.log(error);
});
})
.catch(function(error) {
console.log(error);
});
}
这确实有效,但我不确定我的处理方式是否正确!正在调用的示例函数是这个...
srv.getInitialCharge = function(theItem) {
//set up the deferred var
var deferred = $q.defer();
var initialchargeamount = parseFloat(theItem.normalperiodcharge * theItem.quantity);
if (isNaN(initialchargeamount)) {
deferred.reject("Error when calculating Initial Charge Amount.");
} else {
//set up the failed result
deferred.resolve(initialchargeamount);
}
//return the promise
return deferred.promise;
};
提前感谢您的帮助:)
您创建了一个回调地狱,这正是 Promises 试图避免的。请记住,您还可以 return then
块中的 Promise 以在同一调用链中使用 then
进一步处理它:
function calcNetPriceSaleCharge(theItem) {
var setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem);
var setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
$q.all([setInitialChargeAmount, setDiscountAmount])
.then(function(values) {
theItem.initialchargeamount = values[0];
theItem.initialdiscountamount = values[1];
})
.then(function() {
var setActualCharge = miscSaleSvc.getActualCharge(theItem);
var setVat = miscSaleSvc.setVat(theItem);
return $q.all([setActualCharge, setVat]);
})
.then(function(values) {
theItem.actualcharge = values[0];
theItem.vat = values[1];
})
.then(function() {
var setTotal = miscSaleSvc.getSaleTotal(theItem);
return $q.all([setTotal]);
})
.then(function(values) {
theItem.total = values[0];
})
.catch(function(error) {
console.log(error);
});
}
另一种变体:
function calcNetPriceSaleCharge(theItem) {
var setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem);
var setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
return $q
.all([setInitialChargeAmount, setDiscountAmount])
.then(function(values) {
theItem.initialchargeamount = values[0];
theItem.initialdiscountamount = values[1];
})
.then(function() {
var setActualCharge = miscSaleSvc.getActualCharge(theItem);
var setVat = miscSaleSvc.setVat(theItem);
return $q.all([setActualCharge, setVat]);
})
.then(function(values) {
theItem.actualcharge = values[0];
theItem.vat = values[1];
})
.then(function() {
var setTotal = miscSaleSvc.getSaleTotal(theItem);
return $q.all([setTotal]);
})
.then(function(values) {
return (theItem.total = values[0]);
});
}
calcNetPriceSaleCharge(something)
.then(function(finalValue) {
console.log(finalValue);
})
.catch(function(error) {
console.log(error);
});
为了完整起见,使用 async/await
语法的版本(注意,这可能是 not be available for older browsers)。但是,为了更好的可读性,应该更改变量命名。
async function calcNetPriceSaleCharge(theItem) {
try {
const setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem),
setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
const values0 = await Promise.all( [setInitialChargeAmount, setDiscountAmount] );
theItem.initialchargeamount = values0[0];
theItem.initialdiscountamount = values0[1];
const setActualCharge = miscSaleSvc.getActualCharge(theItem),
setVat = miscSaleSvc.setVat(theItem);
const values1 = await Promise.all( [setActualCharge, setVat] );
theItem.actualcharge = values1[0];
theItem.vat = values1[1];
const values2 = await miscSaleSvc.getSaleTotal(theItem);
theItem.total = values2;
} catch ( e ) {
console.log( e );
}
}
我是编写和使用 promises 的新手,我需要一些建议。我必须遵守我的承诺,因为有些功能只能在其他功能之后 运行。我曾经用很多回调函数来处理这个问题,看起来非常混乱和混乱。但是随着我正在做的链接……它又开始看起来有点乱了,我想知道我这样做是否正确……
function calcNetPriceSaleCharge(theItem) {
var setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem);
var setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
$q
.all([setInitialChargeAmount, setDiscountAmount])
.then(function(values) {
theItem.initialchargeamount = values[0];
theItem.initialdiscountamount = values[1];
})
.then(function() {
var setActualCharge = miscSaleSvc.getActualCharge(theItem);
var setVat = miscSaleSvc.setVat(theItem);
$q
.all([setActualCharge, setVat])
.then(function(values) {
theItem.actualcharge = values[0];
theItem.vat = values[1];
})
.then(function() {
var setTotal = miscSaleSvc.getSaleTotal(theItem);
$q
.all([setTotal])
.then(function(values) {
theItem.total = values[0];
})
.catch(function(error) {
console.log(error);
});
})
.catch(function(error) {
console.log(error);
});
})
.catch(function(error) {
console.log(error);
});
}
这确实有效,但我不确定我的处理方式是否正确!正在调用的示例函数是这个...
srv.getInitialCharge = function(theItem) {
//set up the deferred var
var deferred = $q.defer();
var initialchargeamount = parseFloat(theItem.normalperiodcharge * theItem.quantity);
if (isNaN(initialchargeamount)) {
deferred.reject("Error when calculating Initial Charge Amount.");
} else {
//set up the failed result
deferred.resolve(initialchargeamount);
}
//return the promise
return deferred.promise;
};
提前感谢您的帮助:)
您创建了一个回调地狱,这正是 Promises 试图避免的。请记住,您还可以 return then
块中的 Promise 以在同一调用链中使用 then
进一步处理它:
function calcNetPriceSaleCharge(theItem) {
var setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem);
var setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
$q.all([setInitialChargeAmount, setDiscountAmount])
.then(function(values) {
theItem.initialchargeamount = values[0];
theItem.initialdiscountamount = values[1];
})
.then(function() {
var setActualCharge = miscSaleSvc.getActualCharge(theItem);
var setVat = miscSaleSvc.setVat(theItem);
return $q.all([setActualCharge, setVat]);
})
.then(function(values) {
theItem.actualcharge = values[0];
theItem.vat = values[1];
})
.then(function() {
var setTotal = miscSaleSvc.getSaleTotal(theItem);
return $q.all([setTotal]);
})
.then(function(values) {
theItem.total = values[0];
})
.catch(function(error) {
console.log(error);
});
}
另一种变体:
function calcNetPriceSaleCharge(theItem) {
var setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem);
var setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
return $q
.all([setInitialChargeAmount, setDiscountAmount])
.then(function(values) {
theItem.initialchargeamount = values[0];
theItem.initialdiscountamount = values[1];
})
.then(function() {
var setActualCharge = miscSaleSvc.getActualCharge(theItem);
var setVat = miscSaleSvc.setVat(theItem);
return $q.all([setActualCharge, setVat]);
})
.then(function(values) {
theItem.actualcharge = values[0];
theItem.vat = values[1];
})
.then(function() {
var setTotal = miscSaleSvc.getSaleTotal(theItem);
return $q.all([setTotal]);
})
.then(function(values) {
return (theItem.total = values[0]);
});
}
calcNetPriceSaleCharge(something)
.then(function(finalValue) {
console.log(finalValue);
})
.catch(function(error) {
console.log(error);
});
为了完整起见,使用 async/await
语法的版本(注意,这可能是 not be available for older browsers)。但是,为了更好的可读性,应该更改变量命名。
async function calcNetPriceSaleCharge(theItem) {
try {
const setInitialChargeAmount = miscSaleSvc.getInitialCharge(theItem),
setDiscountAmount = miscSaleSvc.getDiscountAmount(theItem);
const values0 = await Promise.all( [setInitialChargeAmount, setDiscountAmount] );
theItem.initialchargeamount = values0[0];
theItem.initialdiscountamount = values0[1];
const setActualCharge = miscSaleSvc.getActualCharge(theItem),
setVat = miscSaleSvc.setVat(theItem);
const values1 = await Promise.all( [setActualCharge, setVat] );
theItem.actualcharge = values1[0];
theItem.vat = values1[1];
const values2 = await miscSaleSvc.getSaleTotal(theItem);
theItem.total = values2;
} catch ( e ) {
console.log( e );
}
}