我有一个 ASP.NET MVC 应用程序,在 View 中具有以下 javascript 函数:
function OnAmountChanged(s, fieldName, keyValue, url) {
console.log("Get Number: " + s.GetNumber());
console.log(" ");
$.ajax({
type: "POST",
url: url,
data: { key: keyValue, field: fieldName, value: s.GetNumber() },
success: function () {
reloadShoppingCartSummary();
}
});
}
使用向上/向下按钮,我可以增加/减少每次点击调用此函数的字段数量。 通过 console.log,我可以看到 JavaScript 函数是按正确的顺序调用的(我更改数值的顺序)。 但通过在服务器端调试,我注意到它执行调用的顺序是不同的。 什么会导致这个问题? 我该如何解决或解决这个问题?
最佳答案
这一点也不奇怪,也不是你能预料到的。如果您希望以特定顺序处理请求,则必须发送一个请求,等待其响应,然后发送下一个请求。您不能只发送所有这些内容并期望它们按特定顺序进行处理。
在您的具体情况下,如果请求“正在处理”,您必须禁用该按钮,或者将下一个请求排队并在上一个请求完成时播放它。
还有多种发送数据的策略可以防止、适应或检测乱序问题,但使用哪种策略以及如何执行取决于您发送的具体数据及其工作原理客户端和服务器端。
有许多可能的编码策略来处理这个问题。下面是一种方法,可以在处理另一个请求时对传入的任何请求进行排队,强制服务器按顺序处理它们:
var changeQueue = [];
changeQueue.inProcess = false;
function OnAmountChanged(s, fieldName, keyValue, url) {
// if already processing a request, then queue this one until the current request is done
if (changeQueue.inProcess) {
changeQueue.push({s:s, fieldName: fieldName, keyValue: keyValue, url: url});
} else {
changeQueue.inProcess = true;
console.log("Get Number: " + s.GetNumber());
console.log(" ");
$.ajax({
type: "POST",
url: url,
data: { key: keyValue, field: fieldName, value: s.GetNumber() },
success: function () {
reloadShoppingCartSummary();
}, complete: function() {
changeQueue.inProcess = false;
if (changeQueue.length) {
var next = changeQueue.shift();
OnAmountChanged(next.s, next.fieldName, next.keyValue, next.url);
}
}
});
}
}
仅供引用,我认为我们可能会得到为我们完成排队工作的 promise ,但我正在制定一些细节。这是一个正在进行中的想法:http://jsfiddle.net/jfriend00/4hfyahs3/ 。如果您快速按下按钮多次,您可以看到它会将按下的按钮排队并按顺序处理它们。
<小时/>这是通用 Promise 序列化器的具体想法:
// utility function that works kind of like `.bind()`
// except that it works only on functions that return a promise
// and it forces serialization whenever the returned function is called
// no matter how many times it is called in a row
function bindSingle(fn) {
var p = Promise.resolve();
return function(/* args */) {
var args = Array.prototype.slice.call(arguments, 0);
function next() {
return fn.apply(null, args);
}
p = p.then(next, next);
return p;
}
}
function OnAmountChanged(s, fieldName, keyValue, url) {
console.log("Get Number: " + s.GetNumber());
console.log(" ");
return $.ajax({
type: "POST",
url: url,
data: { key: keyValue, field: fieldName, value: s.GetNumber() }
}).then(reloadShoppingCartSummary);
}
var OnAmountChangedSingle = bindSingle(OnAmountChanged);
因此,要使用此代码,您需要将 OnAmountChangedSingle
传递给您的事件处理程序,而不是 OnAmountChanged
,这将强制序列化。
关于javascript - AJAX 调用在服务器端执行的顺序与客户端调用的顺序不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31799949/