[AngularJS面面观] 23. 依赖注入 --- Factory vs Service
据说99%的angular的初学者都会有一个疑问: 比如这个Stackoverflow上的这个问题:Service vs Factory,又或者是这个问题:Service vs Provider vs Factory。 这些问题都有热心答主回答的很棒了,能够解释清它们共同点,区别以及典型用法。因此本文就换个角度,从最根本的角度来看看这两个概念在源代码层次上是如何实现的。 Factory首先,我们来看看 factory: invokeLaterAndSetModuleName('$provide','factory')
// 对于factory而言就是调用: invokeLaterAndSetModuleName('$provide','factory')
function invokeLaterAndSetModuleName(provider,method) {
return function(recipeName,factoryFunction) {
// 在factory函数上设置module名称
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
// 将factory的定义置入任务队列
invokeQueue.push([provider,method,arguments]);
return moduleInstance;
};
}
因此当我们使用该API创建一个 // 假设我们创建一个名为aFactory的factory实例:module.factory('aFactory',function(){})
// 其中的recipeName就是aFactory
function(recipeName,factoryFunction) {
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
invokeQueue.push(['$provide','factory',arguments]);
return moduleInstance;
}
因此和前面讨论过的 function factory(name,factoryFn,enforce) {
return provider(name,{
$get: enforce !== false ? enforceReturnValue(name,factoryFn) : factoryFn
});
}
从上面这段代码就可以看出现端倪了。在 我们知道 只不过 function enforceReturnValue(name,factory) {
return function enforcedReturnValue() {
// 实例注入器完成调用
var result = instanceInjector.invoke(factory,this);
// 如果返回值为undefined,抛出异常
if (isUndefined(result)) {
throw $injectorMinErr('undef',"Provider '{0}' must return a value from $get factory method.",name);
}
return result;
};
}
由于我们平常使用 分析到这里, Service看完了 // Module API
service: invokeLaterAndSetModuleName('$provide','service')
和同样定义在Module API中的 // Injector内部的service函数
function service(name,constructor) {
return factory(name,['$injector',function($injector) {
return $injector.instantiate(constructor);
}]);
}
注意 // 调用的是注入器的instantiate方法,而非invoke方法
return $injector.instantiate(constructor);
另外一个非常非常有意思的地方是, // 内部利用factory完成service的功能
return factory(name,function($injector) {
return $injector.instantiate(constructor);
}]);
在内部创建的 首先我们知道 // providerSuffix就是"Provider"
// protoInstanceInjectorj就是实例注入器
providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
所以最终 简单总结Factory和Service是我们经常用的两个API,它们都能够帮助我们定义依赖注入需要的对象。它们的共同点和不同点简单总结如下: 共同点
不同点
弄清楚了源代码是如何实现factory和service的,再去看看文章开头处提到的那些问题,是不是觉得一切豁然开朗呢? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |