Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
meteor:如何停止异步调用?_Meteor - Fatal编程技术网

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()
    ,以便客户端可以发出更多请求。