Javascript 如何用$q取消承诺
我有下面的服务。每当我打开一个模型,当我关闭该模型,然后再打开另一个模型时,我都会调用此服务。以前的值会得到反映,在这种情况下,我希望在每次关闭该模型时取消承诺 我尝试了以下代码 模型closing.jsJavascript 如何用$q取消承诺,javascript,angularjs,promise,angular-promise,cancellation,Javascript,Angularjs,Promise,Angular Promise,Cancellation,我有下面的服务。每当我打开一个模型,当我关闭该模型,然后再打开另一个模型时,我都会调用此服务。以前的值会得到反映,在这种情况下,我希望在每次关闭该模型时取消承诺 我尝试了以下代码 模型closing.js $scope.closeButton = function() { DetailDataSvc.storeDefer().resolve() } 我的服务,(VC) 有人能帮我确定我遵循的流程是否正确。分配已创建延迟。 尝试并更改此行: self.deferReturn=$q.def
$scope.closeButton = function() {
DetailDataSvc.storeDefer().resolve()
}
我的服务,(VC)
有人能帮我确定我遵循的流程是否正确。分配已创建延迟。 尝试并更改此行:
self.deferReturn=$q.defer()代码>
self.return=d
您尝试的方法可以发挥作用,但最好是将$q.all()
返回的承诺与可拒绝的延迟(即延迟,其中保留对其拒绝方法的引用)进行比较,从而避免错误
注:
$q.race()
对赢得比赛的承诺是透明的,而对其他承诺是不透明的。因此,如果d
在$q.all()
返回的承诺解决之前被拒绝,那么d
将获胜<代码>响应
处理将不会发生,d的拒绝将通过.catch()
子句进行。或者,如果$q.all(promises)
返回的承诺胜出,则流将遵循该承诺的成功路径(即响应
处理)或可能的错误路径(将通过.catch()
子句)
.catch()
回调的签名。您通常希望它接受一个错误
参数避开这个!仅供参考,$q服务现在也有了
.race
方法。@georgeawg,谢谢,这对本练习有很大的影响。我将查看并编辑我的答案。编辑以适应$q.race()
,感谢@georgeawg。
self.storeDefer = function() {
return self.deferReturn;
};
self.getDetailReportData = function(postData, functionName) {
var promises = {};
var d = $q.defer(),
metricDataType;
self.deferReturn = $q.defer();
promises = {
detailReport: metricDataType,
recommendedMetrics: DataSvc.getData(_logPrefix + functionName, recommendedMetricUrl),
metricInfo: DataSvc.getData(_logPrefix + functionName, metricInfoUrl)
};
$q.all(promises).then(function(res) {
$log.debug(_logPrefix + 'getDetailReportData(). Called from %s. $q.all Response (raw): ', functionName, res);
else {
if (response && !_.isEmpty(_.get(response, 'largeCard.chartData.dataValues.rows')) && response.overlayEnabled) {
self.getMetricOverLay(pdata, functionName).then(function(overlayData) {
response.largeCard.chartData.overlay = overlayData;
d.resolve(response);
}, function(msg, code) {
d.reject(msg);
$log.error(_logPrefix + 'getDetailReportData(). Error code: %s. Error: ', code, msg);
});
} else {
d.resolve(response);
}
}
}, function(msg, code) {
d.reject(msg);
$log.error(_logPrefix + 'getDetailReportData(). Error code: %s. Error: ', code, msg);
});
return d.promise;
};
self.getDetailReportData = function(postData, functionName) {
var metricDataType = ......; // ???
var d = $q.defer();
// cancel previous
if(self.cancelDetailReport) {
self.cancelDetailReport(new Error('previous getDetailReportData() cancelled'));
}
// keep a reference to the deferred's reject method for next time round.
self.cancelDetailReport = d.reject;
var promises = {
'detailReport': metricDataType,
'recommendedMetrics': DataSvc.getData(_logPrefix + functionName, recommendedMetricUrl),
'metricInfo': DataSvc.getData(_logPrefix + functionName, metricInfoUrl)
};
// Race aggregated `promises` against `d.promise`, thus providing the required cancellation effect.
return $q.race([$q.all(promises), d.promise])
.then(function(response) {
// arrive here only if all promises resolve and d.reject() has not been called.
$log.debug(_logPrefix + 'getDetailReportData(). Called from %s. $q.all Response (raw): ', functionName, response);
if (response && !_.isEmpty(_.get(response, 'largeCard.chartData.dataValues.rows')) && response.overlayEnabled) {
return self.getMetricOverLay(pdata, functionName)
.then(function(overlayData) {
response.largeCard.chartData.overlay = overlayData;
return response;
});
} else {
return response;
}
})
.catch(function(msg, code) { // signature?
// all error cases including cancellation end up here.
var message = _logPrefix + `getDetailReportData(). Error: (${code}): ${msg}`; // or similar
$log.error(message);
throw new Error(message); // see https://stackoverflow.com/a/42250798/3478010
});
};