如何使 Meteor 方法同步?
Posted
技术标签:
【中文标题】如何使 Meteor 方法同步?【英文标题】:How to make Meteor methods synchronous? 【发布时间】:2014-05-05 07:27:50 【问题描述】:我需要一种让流星调用同步的方法,以便在运行调用时,代码等待结果完成,以便可以继续到客户端上的下一行代码。
例如:
clientFunction = function()
Meteor.call('serverFunction', function(err,result))//<--so when this gets a result and
//is stored in a session variable
var doSomeThing = Session.get('whatever') <-- so that your able to use it here
我尝试使用 while 循环来防止在返回值之前发生任何事情,但它似乎在 clientFunction 之后运行,因此将其推向了死亡
任何帮助将不胜感激
【问题讨论】:
你为什么不在回调中设置/做一些事情呢? 我会这样做,直到客户端代码运行完成后才会设置值 如果您多解释一下您正在尝试做什么,这可能会有所帮助。使用您当前的代码,您可以将您的var doSomething
代码移动到回调中。根据您所拥有的,没有理由不这样做。阻止客户端不是一个好主意,这就是异步回调旨在防止的。
我有 7 个带有指定分离类的集合来处理单个级别的类,例如 this.add = function (name, number,status,type, brand, agency) return Projects.插入(名称:名称,编号:编号,状态:状态,可见性:true,dateCreated:新日期(),dateModified:新日期(),类型:类型,品牌:品牌,机构:机构,点:[],存档:假); ;但我不能在函数中调用来重新运行值
【参考方案1】:
我按照this 教程做了类似下面的操作
这是一个流星服务器端方法
productIdResult:function(searchstring)
var skimlinks_query = Async.wrap(skimlinks.query);
var title_val="title:\"electric bicycle\" AND merchantCategory:*bikes*";
var result = skimlinks_query(
searchFor: searchstring,
start:start,
rows:rows,
fq: "country:US"
);
return result;
我这样从客户那里调用它
Meteor.call('productIdResult',
searchstring,
function(error,resul)
arr[0]=resul.skimlinksProductAPI.products[0].title;
$( "#op1").autocomplete(source:arr);
);
注意不是同步的,而是在回调中获取返回值
【讨论】:
【参考方案2】:这是一个非常常见的问题,被以各种形式和形式提出。大多数人在进行异步调用时都没有意识到。然而,解决方案始终是相同的:将服务器上的方法代码包装到纤程中或使用未来。
我认为,最佳做法是使用当前可用的 Meteor._wrapAsync
函数,如所述,例如,此处:
Meteor: Calling an asynchronous function inside a Meteor.method and returning the result
这里描述了一些其他选项: https://gist.github.com/possibilities/3443021
更新:该方法现在称为Meteor.wrapAsync
。
【讨论】:
我确实尝试过这个并且控制台一直吐出“对象没有方法_wrapAsync”对象含义流星 您可能在拜访客户吗?我刚刚确认,在上两个版本的流星中,这个功能仍然存在:在服务器上:console.log(Meteor._wrapAsync)
打印[Function]
,即它存在。【参考方案3】:
将方法完成后要运行的代码放入方法回调中。这是任何异步 javascript 的标准。
clientFunction = function()
Meteor.call('serverFunction', function(err, result)
if (err)
alert(err);
else
Session.set('whatever', result.whatever);
);
;
一旦方法调用返回,它就会设置会话变量的值。现在您使用 Meteor 的反应性来使用该变量:
Template.hello.helpers(
myWhatever: function ()
var whatever = Session.get('whatever');
if (whatever) return whatever;
return 'Loading whatever...';
);
【讨论】:
如果您正在等待Meteor.call
的值在下一行代码中执行一些操作,则此方法不起作用...
Meteor.call
是异步的,这意味着根据定义,Meteor.call
之后的下一行代码不会等待其完成。这就是任何异步调用的工作方式。这就是异步调用有回调的原因,允许您仅在结果返回后执行代码。如果您需要等待返回值,则需要将“您的下一行代码”放入回调中。
为了完整起见,Meteor 提供了一种替代方法,可以将依赖于返回值的代码放在回调中。相反,让依赖于返回值的代码使用反应变量(如Session
),然后在回调中将返回值存储在反应变量中。
我完全理解异步调用,我说你的解决方案只适用于模板,因为反应性属性而不是通用解决方案,_wrapAsync
看起来是一个更好的方法......
将依赖于远程调用结果的代码放入回调中是一种通用解决方案,并且是编写 javascript 异步代码的标准方式。 Meteor 在服务器端使用Fibers 来避免这种情况。这个问题的上下文是在客户端上运行的代码(我们可以这样说,因为原始问题包括使用Session
,这是仅限客户端的)。 wrapAsync
(使用 Fibers)是服务器端代码的一个很好的解决方案。在客户端,你必须使用我上面展示的回调方法。以上是关于如何使 Meteor 方法同步?的主要内容,如果未能解决你的问题,请参考以下文章
初识Angular-Meteor(Angular-Meteor使实时全栈更简单)
Meteor 的 DDP 在同步非常大的集合方面的效率如何?