meteor:如何停止异步调用?

时间:2017-02-20 18:35:35

标签: meteor

是否可以停止(终止)异步调用?

在我的应用程序中,我在客户端就像:

Meteor.call('doCalculation', function(err, result) {
  //do sth with result
});

'doCalculation'可能需要很长时间(这没关系)我不希望用户在他/她已经有一个正在运行的呼叫时开始新呼叫,我想允许用户停止当前呼叫并提交新呼叫。这是怎么做到的?

我唯一的想法是使用mongo在客户端和服务器之间进行通信。在'doCalculation'函数中的某些地方,我可以观察一些mongo文档/集合,并在此基础上执行函数(例如调用异常)。你有更好的想法吗?

3 个答案:

答案 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种情况:

  1. 用户重新加载浏览器
  2. 用户使用2个浏览器
  3. 我会创建这些方法:

    1. isCalculationActive() - 检查用户是否已激活计算。在服务器上,您可以将该事实保留在内存中或将其写入数据库。在客户端上,如果返回false,则可以继续调用doCalculation()。如果为true,您可以向用户提供弹出窗口或提醒,或者询问他们是否要取消并继续操作。

    2. doCalculation() - 这将取消该用户的任何未完成计算并启动一个新计算。

    3. 实现这些后,用户可以重新加载他们的浏览器,不会影响正在运行的计算或正确的行为。如果他们尝试第二个浏览器,一切都应该按预期工作。

      如果您想让用户选择简单地停止作业而不是开始新作业,那么您只需创建:

      1. cancelCalculation() - 这将取消该用户的任何未完成计算。