我有以下代码导致两次调用Webtrends被取消(即这两个调用在浏览器时没有给出http 200但是在浏览器的网络选项卡中有一条被取消的消息)
mercury.Tracking.logUsage("export", GetSelectedExportType(form));
mercury.Tracking.logUsage('exportchart', mercury.ChartContainer.currentChartUri(), path);
form[0].submit();
我以这种方式重写了这一点以避免这个问题,因为在我看来,之所以取消对Webtrends的调用是因为表单提交是这样的,所以在调用表单上的提交之前我等了两秒钟
mercury.Tracking.logUsage("export", GetSelectedExportType(form));
mercury.Tracking.logUsage('exportchart', mercury.ChartContainer.currentChartUri(), path);
var submit = function () {
setTimeout(function() {
form[0].submit();
}, 2000);
};
submit();
问题是,有更好的方法,使用承诺或回调或其他任何方法吗?
logUsage代码是
(function ($, window) {
function Tracking() {
}
Tracking.prototype.chartTitle = function () {
return $('#chartNameInfo').text();
};
Tracking.prototype.hostName = function () {
return $('#trackingVars').data('host-name');
};
Tracking.prototype.page = function () {
return $('#trackingVars').data('page');
};
Tracking.prototype.currentUser = function () {
return window.config.userId;
};
Tracking.prototype.logUsage = function (action, resourceUri, actionTargetUri, additionalTags) {
// action: action performed - e.g. create, delete, export
// resourceUri: URI of API resource *on* which action is being performed (required), e.g. /users/current/annotations/{annotation-id}
// actionTargetUri: URI of API resource *to* which action is being performed (optional), e.g. /charts/{chart-id}
if (action.indexOf("DCSext.") < 0) {
action = "DCSext." + action;
}
var jsonString = '{"' + action + '"' + ':"1"}';
var jsonObj = JSON.parse(jsonString);
if (additionalTags == null) {
additionalTags = jsonObj;
}
else {
additionalTags = $.extend({}, additionalTags, jsonObj); //Append two JSON objects
}
var trackingargs = $.extend({
'DCSext.resource-uri': resourceUri,
'DCSext.action-target-uri': actionTargetUri,
'WT.ti': this.chartTitle(),
'DCSext.dcssip': this.hostName(),
'DCSext.em-user-id': this.currentUser(),
dsci_uri: this.page()
}, additionalTags);
try {
WebTrends.multiTrack({ args: trackingargs });
} catch (e) {
console.log(e);
}
};
window.Tracking = new Tracking();
$(function() {
$('body').on('click', 'a[data-tracking-action]', function() {
window.Tracking.logUsage($(this).data('tracking-action'), $(this).data('tracking-resource'));
});
$(document).on('attempted-access-to-restricted-resource', function(event, href) {
window.Tracking.logUsage('unauthorisedResourceAccessUpsell', href.url);
});
});
})(jQuery, window);
答案 0 :(得分:3)
如果提供了额外的信息,我想我现在可以回答你的问题了。
从WebTrends doc,您可以为WebTrends.MultiTrack调用添加完成回调。 你能做什么:
Tracking.prototype.logUsage = function (action, resourceUri, actionTargetUri, additionalTags) {
...
var finished = $.Deferred();
...
try {
WebTrends.multiTrack({ args: trackingargs, finish: function(){finished.resolve();}});
}
...
return finished;
}
然后在你的代码中:
$.when(mercury.Tracking.logUsage("export", GetSelectedExportType(form)),
mercury.Tracking.logUsage('exportchart', mercury.ChartContainer.currentChartUri(), path))
.done(function(){
form[0].submit();
});
我没有对此进行测试,但我认为它应该可行。希望它有所帮助。
说明:
描述:提供一种基于one执行回调函数的方法 或更多对象,通常是表示异步的延迟对象 事件
基本上,jQuery.when()将接受一个或多个延迟(构建承诺)或承诺,并将返回一个在它们全部满足时履行的承诺。从那里,我们可以选择使用.done()或.then()
方法将处理程序添加到我们的承诺中,该承诺将被调用一次或承诺完成。 (promise表示异步操作的结果)。
因此,在上面的代码中,我在您的logUsage
方法中创建了一个新的延迟对象,并且该方法返回延迟,因此您可以将这些延迟传递给jQuery.when
方法,何时它们将是实现(这就是我在WebTrends.Multitrack
调用中添加完成回调的原因),传递给deferred.done()
的处理程序将被执行。
我希望这不会太混乱,我不确定我是否正确解释它。
答案 1 :(得分:2)
不想偷走Antoine的代表。他的回答基本上很好,但...
部分可以比问题更有效地加以充实,还有一些其他要考虑的要点。
Tracking.prototype.logUsage = function (action, resourceUri, actionTargetUri, additionalTags) {
// action: action performed - e.g. create, delete, export
// resourceUri: URI of API resource *on* which action is being performed (required), e.g. /users/current/annotations/{annotation-id}
// actionTargetUri: URI of API resource *to* which action is being performed (optional), e.g. /charts/{chart-id}
try {
// you might as well wrap all the preamble in the try{}, just in case it it error-prone
if (action.indexOf("DCSext.") < 0) {
action = "DCSext." + action;
}
//trackingargs can be defined efficiently as follows, avoiding the need for the variable `jsonObj` and the ugly JSON.parse().
var trackingargs = $.extend({
'DCSext.resource-uri': resourceUri,
'DCSext.action-target-uri': actionTargetUri,
'WT.ti': this.chartTitle(),
'DCSext.dcssip': this.hostName(),
'DCSext.em-user-id': this.currentUser(),
'dsci_uri': this.page()
}, additionalTags || {}); // `additionalTags || {}` caters for missing or null additionalTags
trackingargs[action] = 1;//associative syntax gets around the limitation of object literals (and avoids the need for JSON.parse()!!!).
//to keep things tidy, return $.Deferred(fn).promise()
return $.Deferred(function(dfrd) {
WebTrends.multiTrack({
args: trackingargs,
finish: dfrd.resolve //no need for another function wrapper. `$.Deferred().resolve` and `$.Deferred().reject` are "detachable"
});
}).promise();//be sure to return a promise, not the entire Deferred.
} catch (e) {
console.log(e);
//Now, you should really ensure that a rejected promise is always returned.
return $.Deferred.reject(e).promise();//Surrogate re-throw.
}
};
查看代码中的评论
由于Tracking.prototype.logUsage
现在可以返回被拒绝的承诺,并且您可能不希望.logUsage()
无法阻止您的表单提交,您可能希望将已拒绝的承诺转换为已完成。
$.when(
mercury.Tracking.logUsage("export", GetSelectedExportType(form)).then(null, function() {
return $.when();//resolved promise
}),
mercury.Tracking.logUsage('exportchart', mercury.ChartContainer.currentChartUri(), path).then(null, function() {
return $.when();//resolved promise
})
).done(function() {
form[0].submit();
});
然而,返回被拒绝的承诺然后转换为成功似乎是一种不必要的复杂化:
window.Tracking.logUsage()
可能会在您的代码中的其他位置调用,因此必须将错误视为错误。