javascript - 如何在角度 js 中用 $q 取消承诺
问题描述
我在下面有一个服务。每次打开模型时我都会调用此服务,当我关闭模型然后打开另一个模型时,以前的值会得到反映,在这种情况下,我想在每次关闭模型时取消承诺。
我试过下面的代码,
模型关闭.js
$scope.closeButton = function() {
DetailDataSvc.storeDefer().resolve()
}
我的服务,(DetailDataSvc)
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;
};
谁能帮助我我遵循的过程是否正确。
解决方案
您尝试过的事情可能会起作用,但最好通过将返回的承诺$q.all()
与可拒绝的 Deferred (即 Deferred,其中引用保留对其拒绝方法)竞争来解决,从而避免延迟的反模式。
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
});
};
笔记:
$q.race()
对赢得比赛的承诺是透明的,对另一个承诺是不透明的。因此,如果在结算d
返回的承诺之前被拒绝,那么将胜出;处理将不会发生,d 的拒绝将落入该条款。或者,如果获胜返回的承诺,那么流程将遵循该承诺的成功路径(即处理)或可能的错误路径(将通过子句)。$q.all()
d
response
.catch()
$q.all(promises)
response
.catch()
不太确定
.catch()
回调的签名。您通常会期望它接受一个error
参数。
推荐阅读
- web-scraping - Python 3.7- PhantomJS - Driver.get(url) 与“窗口句柄/名称无效或关闭?”
- javascript - 将 axios 请求的响应推送到数组中
- codeigniter - Codeigniter中的内部连接与多个表
- angular - Angular Subject 不听变化
- c++ - 无法使用 fstream 从二进制文件中读取字符串,而是显示奇怪的符号
- python - 在python中匹配之前添加文本2行
- python - 即使我的 MQTT 客户端未连接,我如何继续运行我的程序?
- php - If 语句不显示 else 结果
- typescript - 如何根据条件将可选属性设置为必需?
- node.js - 任何redis调用的ioredis发送命令的默认超时是多少