是否可以停止(终止)异步调用?
在我的应用程序中,我在客户端就像:
Meteor.call('doCalculation', function(err, result) {
//do sth with result
});
'doCalculation'可能需要很长时间(这没关系)我不希望用户在他/她已经有一个正在运行的呼叫时开始新呼叫,我想允许用户停止当前呼叫并提交新呼叫。这是怎么做到的?
我唯一的想法是使用mongo在客户端和服务器之间进行通信。在'doCalculation'函数中的某些地方,我可以观察一些mongo文档/集合,并在此基础上执行函数(例如调用异常)。你有更好的想法吗?
答案 0 :(得分:0)
您可以使用semaphore
来实现此目的。当semaphore
为1时,允许发送请求。当semaphore
为0时,不允许发送请求。默认情况下,信号量应为1,并且在发送请求之前,需要将其设置为0.如果响应成功,则将semaphore
设置为1。
关于超时:您可以在发送请求后使用setTimeout
使用超时,如下所示:
if (semaphore) {
var isTimedOut = false;
var isSuccess = false;
semaphore = 0; //No need to use var keyword, as this should be declared outside of this scope
Meteor.call('doCalculation', function(err, result) {
isSuccess = true;
//do sth with result
});
setTimeout(function() {
if (!isSuccess) {
isTimeout = true;
//do something else, to handle the time out state
}
}, 10000);
}
答案 1 :(得分:0)
这很棘手,因为您通常无法从客户端的角度设置超时。出于一系列架构原因,您并不需要这样做。最重要的是,如果丢失网络连接或服务器崩溃(两种情况超时设计为管理),客户端立即意识到它是断开的。如果经常发生这种情况,您可以使用Meteor.status().connected
。
听起来你在服务器上运行了很长的计算。我的建议是立即返回calculationId
,然后根据进度更新集合,例如CalculationProgresses.update(calculationId, {$set: {progress: currentProgress}})
。然后,您的UI可以以最方便的方式自动更新进度。
请注意,当您在服务器上运行长时间计算时,您需要偶尔"产生,"给予其他工作机会。如果你不掌握这种屈服的概念,那么Meteor所基于的节点对于长时间的计算是很棘手的。在Meteor中,您可以通过更新集合(例如,您的进度集合)轻松获得。这将解决您在编写应用程序时可能遇到的许多问题。
答案 2 :(得分:0)
我认为您需要一个服务器端解决方案。如果您使用客户端解决方案,则不会处理2种情况:
我会创建这些方法:
isCalculationActive() - 检查用户是否已激活计算。在服务器上,您可以将该事实保留在内存中或将其写入数据库。在客户端上,如果返回false,则可以继续调用doCalculation()。如果为true,您可以向用户提供弹出窗口或提醒,或者询问他们是否要取消并继续操作。
doCalculation() - 这将取消该用户的任何未完成计算并启动一个新计算。
实现这些后,用户可以重新加载他们的浏览器,不会影响正在运行的计算或正确的行为。如果他们尝试第二个浏览器,一切都应该按预期工作。
如果您想让用户选择简单地停止作业而不是开始新作业,那么您只需创建: