【问题标题】:Non-blocking code execution非阻塞代码执行
【发布时间】:2016-07-20 02:26:58
【问题描述】:

我有一个定义某些方法的 Meteor 项目。在那些中,发送电子邮件。由于这需要大量时间并且会减慢最终用户的整个操作速度,因此我想异步发送电子邮件。邮件发送成功与否对方法调用的结果没有影响。

据我发现,使用setTimeout 模拟异步调用很常见。在这种情况下我也应该这样做吗?

编辑: cmets 中要求的代码

export const UpdateMaterial = new ValidatedMethod({
    name: 'material.update',
    validate: new SimpleSchema({
        id: {type: String},
        description: {type: String},
    }).validator(),
    run({id, description}){
        const _id = new Meteor.Collection.ObjectID(id);

        let res;
        if(Meteor.isServer) {
            res = Materials.update({_id}, {
                $set: {
                    'metadata.description': description
                }
            });
         }
        SendHTMLEmailToRoles(Titles.NewMaterial,Texts.NewMaterial, [Roles.Admin]);
        return res;
    }
});

export const SendHTMLEmailToRoles = (subject,html,roles) => {
    if(Meteor.isServer) {
        const users = Meteor.users.find({role: {$in: roles}}).fetch();
        const addresses =  users.map(function(user){
            if(!user.emails)
                return;
            return user.emails.pop().address;
        });
        Email.send({
            to: addresses,
            from: 'test@test.com',
            subject,
            html
        });
    }
}

【问题讨论】:

  • 你的代码是什么?
  • @epascarello 编辑了问题
  • @SergioTulentsev 我知道如何发送电子邮件,异步部分是问题
  • 好吧,那里的文档说“异步发送电子邮件”。

标签: javascript jquery asynchronous meteor


【解决方案1】:

如果我的理解是正确的,那么您展示的整个代码都是 Meteor 方法?

在这种情况下,调用它根本不会阻塞客户端,因为所有 Meteor 调用都是异步的。这就是您可以提供回调的原因。

但是,如果不仔细设计,服务器上的 Meteor 方法是同步的。因此,如果客户进一步拨打电话,则在电子邮件实际发送之前不会对其进行处理。

要恢复服务器上发送电子邮件的一些异步行为,请注意 Sergio (https://docs.meteor.com/api/email.html) 提供的参考页面示例中的 this.unblock()

现在,如果您希望立即执行您的 Meteor 调用客户端回调,而无需等待 Email.send() 完成,您将不得不延迟该指令(通常通过确实用 setTimeout 包装它)让您的Meteor 方法返回。

【讨论】:

  • 是的,可以访问其他方法(通过调用 this.unblock())不是我关心的问题,我需要的只是立即执行的回调。我传递给函数的延迟重要吗?
  • 延迟(以毫秒为单位)取决于您希望服务器在实际调用 Email.send() 指令之前执行的操作。大多数时候0 就足够了,因为您只希望将指令推送到进程队列的末尾,以便之前可以执行其他待处理的任务(包括 Meteor 方法的其余部分)。
  • 哦,谢谢,不知道有一个选项可以在最后推送执行。
  • 这实际上是 JS 管理调用的方式:它们只是被推送到队列中。 setTimeout 只是在给定延迟后推送一个新任务,但实际上只有在队列中的先前任务处理完毕后才会执行该任务。
  • 这是否意味着延迟相当“最小保证延迟”,就好像一个长任务在调用超时之后开始执行并且在超时之前将超时任务推入队列,超时任务将在之后执行跑步者完成了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 2016-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
相关资源
最近更新 更多