meteor:如何停止异步调用?
是否可以停止(终止)异步调用 在我的应用程序中,我在客户端有如下内容:meteor:如何停止异步调用?,meteor,Meteor,是否可以停止(终止)异步调用 在我的应用程序中,我在客户端有如下内容: Meteor.call('doCalculation', function(err, result) { //do sth with result }); “doCalculation”可能需要很长时间(这没关系)我不希望用户在已经有一个正在运行的呼叫时启动新呼叫,我希望允许用户停止当前呼叫并提交新呼叫。如何正确地做到这一点 我唯一的想法就是使用mongo在客户端和服务器之间进行通信。在“doCalculation”函
Meteor.call('doCalculation', function(err, result) {
//do sth with result
});
“doCalculation”可能需要很长时间(这没关系)我不希望用户在已经有一个正在运行的呼叫时启动新呼叫,我希望允许用户停止当前呼叫并提交新呼叫。如何正确地做到这一点
我唯一的想法就是使用mongo在客户端和服务器之间进行通信。在“doCalculation”函数中的某个地方,我可以观察一些mongo文档/集合,并在此基础上在函数中做某事(例如调用异常)。你有什么更好的主意吗?你可以使用
信号灯来达到这个目的。当信号量
为1时,允许发送请求。当信号量为0时,不允许发送请求。默认情况下,信号量应为1,在发送请求之前,需要将其设置为0。当响应成功时,将信号量设置回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);
}
这很棘手,因为通常不能从客户的角度设置超时。出于一些架构上的原因,您不需要这样做。最重要的是,如果您失去网络连接或服务器崩溃(有两种情况是为了管理超时),客户机会立即意识到,因为它已断开连接。如果经常发生这种情况,可以使用Meteor.status().connected
听起来您在服务器上运行了一个很长的计算。我的建议是立即返回calculationId
,然后用progress更新集合,例如,calculationprogress.update(calculationId,{$set:{progress:currentProgress}})
。然后,用户界面可以以最方便的方式反应性地更新进度
请注意,当您在服务器上运行长时间计算时,您需要偶尔“让步”,以便有机会进行其他工作。Meteor所基于的节点,如果您不掌握屈服的概念,则很难进行长时间的计算。在Meteor中,您可以通过更新一个集合(例如,您的进度集合)来轻松生成。这将解决您在编写应用程序时可能遇到的许多问题。我认为您需要一个服务器端解决方案。如果使用客户端解决方案,则不会处理以下两种情况:
用户将重新加载其浏览器
用户使用2个浏览器
我将创建以下方法:
isCalculationActive()--检查用户是否已激活计算。在服务器上,您可以将该事实保留在内存中,也可以将其写入数据库。在客户端上,如果返回false,则可以继续调用doccalculation()。如果为true,您可以向用户提供弹出窗口或警报或询问用户是否要取消并继续
doCalculation()--这将取消该用户未完成的任何计算,并开始新的计算
实现这些功能后,用户可以在不影响运行计算或正确行为的情况下重新加载浏览器。如果他们尝试第二个浏览器,一切都应该按预期工作
如果您想让用户选择仅停止作业而不启动新作业,则可以简单地创建:
cancelCalculation()--这将取消该用户未完成的任何计算
谢谢你的回复,但这不是我问题的答案。我无法设置超时,在这种情况下,没有长时间呼叫。在相同的情况下,通话可能需要几秒钟(或更短)的时间,在相同的其他几分钟内,两者都可以。我不想强迫用户等待他/她的作业结束(因为我写的长作业通常是正确的,我不能禁止它)。我确实希望用户能够停止作业。@rmg一旦您的浏览器发送了请求,它就会被发送。您无法取消发送它,因为它不再在您控制的计算机上。您唯一能做的就是以这样一种方式实现回调:它将忽略超时后到达的响应,并控制等待限制。这个答案解释了你如何做到这一点。关于你关于屈服的评论,纤维能解决这个问题吗?i、 e.将长时间运行的操作封装在光纤中可以解决成品率问题,还是一开始只能生产一次?我想更好地理解这一点。您可以为长时间运行的操作创建光纤(Meteor.bindEnvironment
为您这样做,Meteor.async
)。在MongoCollection::update
中,最终会调用Fiber.yield()
,这就是为什么更新集合也会起作用。确保在方法中调用this.unblock()
,以便客户端可以发出更多请求。