在Meteor.call()
的Meteor文档中,它显示为:
如果你包含一个回调函数作为最后一个参数(它不能作为方法的参数,因为函数不可序列化)......
我之前运行过与Meteor.call('name', function() {console.log('abc');}, function() {})
类似的内容,其中function() {console.log('abc');}
作为 参数 传入,空function() {}
用作异步回调的存根。 它有效。
该声明告诉我,我不应将 任何 函数作为函数的参数传递,或仅适用于回调函数。
在任何一种情况下,为什么该功能不可序列化?我的浅薄理解只是可序列化的对象是一个可以将其转换为位序列(1
' s和0
' s)的对象,并且因为一切数字是比特序列,我不明白为什么函数不可序列化。
我发现了一些explanations,但它们都与Java有关,对于那些还不了解序列化重要性的人来说,它没什么帮助。
为什么函数不可序列化?(以及它与Meteor.call()
的关系如何?)
答案 0 :(得分:7)
在大多数情况下,可序列化意味着您可以将某些内容转换为与语言无关的表示形式,并在其他位置重建原始状态。例如。数组[0,1,2]
可以序列化为JSON "[0,1,2]"
并在其他地方反序列化。
在任何一种情况下,为什么该函数不可序列化?
一个函数对象(在JS中)由两部分组成:它的主体(代码)和它所定义的环境。每个函数都是一个闭包。获取函数的来源很简单,但是无法获得其环境状态。
示例:
var foo = 42;
function bar() {
console.log(foo);
}
thirdService(bar);
thirdService
不知道定义函数的环境。它所能做的就是获取函数体的字符串表示,但它不知道foo
的值
答案 1 :(得分:2)
该声明的Meteor文档意味着API(Meteor.call
)可以告诉您将回调作为最后一个参数传递,因为它知道函数的参数不能是要传递给服务器的参数之一,因为它们必须可序列化为JSON。
所以:当你使用Meteor.call()
来调用方法时,第一个参数是要调用的方法的名称。然后将零个或多个参数传递给方法,并且每个参数必须可表示为JSON。最后,如果你想要一个异步回调,你将它作为最后一个参数传递。
与Meteor.apply()
形成对比,后者执行相同的操作,但需要三个参数:方法名称,参数值数组和(可选)回调。因为所有方法参数都在数组中,所以不需要做任何“嗅探”来判断是否存在回调参数。
答案 2 :(得分:1)
我认为这归结为事物序列化的格式。通常使用我遇到的每个例子都使用JSON来序列化Javascript对象,而简单地说JSON不支持function
数据类型。
如果查看json.org,您可以看到支持数据类型。您可以在同一站点中看到下图中支持的不同值:
最接近函数的是将它表示为一个字符串,但是在反序列化过程中没有什么可以告诉你如何将它重新补充回Javascript函数。
答案 3 :(得分:1)
以下列对象为例
var aFancyValue = 123;
var obj = {
propName: "A value"
funcName: function(){
// you do something fancy with aFancyName variable
}
}
现在,当您尝试序列化obj
时,如果函数是可序列化的,那么aFancyValue
应该有一些其他方式可以使函数无法正常工作。
其他内容如属性是文字,他们不依赖于其他任何东西。它们本身是完整的,但可能的函数可能与它们不同,因为它们可能依赖于数据,这些数据在序列化时可能无法访问。
简而言之,环境,功能的上下文未知,这就是他们无法序列化的原因。