繁体   English   中英

使Meteor.methods同步和异步

[英]Make Meteor.methods Synchronous and Asynchronous

有时我需要Meteor.call将writeMeLater排队并同步执行(阻止来自同一客户端的writeMeLater其他调用)。

其他时候,应尽快执行对writeMeLater的调用,而不排队当前排队的所有呼叫。

以下是我的尝试,如果async参数为true,则使用this.unblock() 案例1和2工作正常。 但是在案例3中, async=true调用正在使用async=false调用! 我们如何使用async=true进行调用跳过队列? 这类似于第一个客户端调用后来自第二个客户端的呼叫未排队的情况,

所有Meteor.call()都是由客户端制作的

案例1(正确同步):

Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)

案例2(正确异步):

Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)

案例3(不是理想的行为)

Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)
Meteor.call('writeMeLater', 's', false)

Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)
Meteor.call('writeMeLater', 'a', true)

服务器/ main.js

writeMeLater = function(data, callback) {
    console.log('writeMeLater: ', data)

    // simulate taking 3 second to complete
    Meteor.setTimeout(function() {
        Logs.insert({data: data, timestamp: new Date().getTime()})
        console.log('Log.insert: ', data)
        callback(null, 'done')
    }, 3 * 1000)
}



writeMeLaterSync = Meteor._wrapAsync(writeMeLater)



Meteor.methods({

    writeMeLater: function(data, async) {
        if(async)
            this.unblock()

        writeMeLaterSync(data)
    }

})

我的第一个想法是,为什么不实际创建队列? 而不是依赖JavaScript事件循环作为您的队列。 然后将文档插入该队列,如:

WritesQueue = new Meteor.Collection("WritesQueue");
WritesQueue.insert({data: 'a', prioritize: true, inserted: new Date()});

也许每次插入高优先级写入时,触发处理队列的Meteor.call("write") ,优先级(非异步)首先执行:

Meteor.methods({
  write: function () {
    WritesQueue.find({prioritize: true}, {sort: {inserted: 1}})
    .forEach(function (doc) {
      console.log(doc.data);
      WritesQueue.remove(doc._id);
    });
    WritesQueue.find({prioritize: false}, {sort: {inserted: 1}})
    .forEach(function (doc) {
      console.log(doc.data);
      WritesQueue.remove(doc._id);
    });
  }
});

或者,如果您希望每次插入高优先级或低优先级写入时都处理队列,请随时调用write方法或将insert write方法本身。 这解决了跳转到线头的问题,尽管每个客户端仍然会同步处理写入。

至于尝试为单个客户端实现并行处理,@imslavko(在上面的问题的评论中)是正确的,因为实现此目的的一种方法是客户端建立多个DDP连接。 有一个相对简单,虽然hacky和非流星,这样做的方式:

安装Iron Router并在服务器代码中定义服务器端路由:

Router.map(function () {
  this.route('writeMeLater', {
    where: 'server',
    action: function () {
      Meteor.call('writeMeLater',
        this.request.query.data, this.request.query.async);
    }
  });
});

上面的this.request.query是一个带有键值对的对象,您随请求一起提交。 例如:

HTTP.post("http://yoursite.com/writeMeLater",
  {params: {data: 'a', async: true}});

就服务器所知,此请求来自新客户端,因此将在新的光纤(即线程)中处理。 如果writeMeLater方法知道不等待,它的许多实例可以同时开始运行。 现在问题变得依旧保持请求,如果对您来说服务器上的执行顺序与客户端上的执行顺序一样重要,因为HTTP POST请求可能不一定以与它们相同的顺序到达服务器。发送。 但是也有各种方法可以处理它(分批发送它们,或者包括一个计数器,如果它检测到一个不按顺序的请求,让服务器等待几秒钟等)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM