【发布时间】:2015-05-04 18:35:32
【问题描述】:
假设我们有两个按钮,每个按钮都调用以下方法:
var NUMBER_OF_IMAGE_REQUEST_RETRIES = 3;
var IMAGE_REQUEST_TIMEOUT = 3000;
processImage: function(image_data) {
var main_response = $q.defer();
var hash = getImageHash(image_data);
var requestsCounter = -1;
requestImage = function() {
$http.post(apiUrl, {params: {data: hash},timeout: IMAGE_REQUEST_TIMEOUT})
.then(function(response) {
return main_response.resolve(response.data);
}, function(error) {
if (++requestsCounter < NUMBER_OF_IMAGE_REQUEST_RETRIES) {
requestLabelsImage();
} else {
return main_response.reject();
}
});
};
requestLabelsImage();
return main_response.promise;
}
该方法将图像相关数据传递给服务器,服务器处理数据然后响应。每次用户按下不同的按钮时,都会向服务器发送不同的image_data。
问题:
用户按下按钮1,方法被image_data_1调用,然后他/她立即按下按钮2,方法被image_data_2调用。 processImage 函数由另一种方法调用,假设 doSomethingWithTheResponse 只关心最新用户的操作,但 image_data_2 由服务器执行得更快,因此客户端在 image_data_1 之前获得 image_data_2,所以客户认为image_data_1与用户最近的操作有关,事实并非如此。 我们如何确保客户端始终获得与用户最新操作相关的响应?
注意:不同image_data 请求的哈希值不同。
我在想这样的事情:
var oldhash = null;
processImage: function(image_data) {
var main_response = $q.defer();
var hash = getImageHash(image_data);
oldhash = hash;
var requestsCounter = -1;
requestImage = function(hash) {
if(hash === oldhash){
$http.post(apiUrl, {params: {data: hash},timeout: IMAGE_REQUEST_TIMEOUT})
.then(function(response) {
return main_response.resolve(response.data);
}, function(error) {
if (++requestsCounter < NUMBER_OF_IMAGE_REQUEST_RETRIES) {
requestLabelsImage(hash);
} else {
return main_response.reject();
}
});
}
else {
main_response.reject();
}
}
requestLabelsImage(hash);
return main_response.promise;
}
但我不能 100% 确定这是正确的方法。
【问题讨论】:
-
你不能在按下第二个按钮时取消第一个请求吗? developer.mozilla.org/en-US/docs/Web/API/…
-
“不要让你的用户做他们应该做的事情”。为什么不让按钮 2 处于禁用状态,直到按钮 1 的响应返回并得到处理?
-
@Mike'Pomax'Kamermans 因为根据 UI/UX 要求,用户应该能够以任意顺序单击按钮(并向服务器发送请求),但客户端应该呈现他最近行动的结果。
-
你也可以过滤。
if (image_data_1) { /* do this */} if (image_data_2) { /* do that */}.
标签: javascript angularjs asynchronous