第一篇: vscode源码分析【一】从源码运行vscode
第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第四篇:vscode源码分析【四】程序启动的逻辑,最初创建的服务
第五篇:vscode源码分析【五】事件分发机制

细心的读者可能会发现,在第四篇文章中的createService方法中,并没有把所有的服务实例化,下面这些服务,只是记了他们的类型:
src\vs\code\electron-main\main.ts

		services.set(ILifecycleService, new SyncDescriptor(LifecycleService));
services.set(IStateService, new SyncDescriptor(StateService));
services.set(IRequestService, new SyncDescriptor(RequestService));
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService));
services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
services.set(ISignService, new SyncDescriptor(SignService));

SyncDescriptor负责记录这些服务的类型,以供后续使用
(src\vs\platform\instantiation\common\descriptors.ts)

export class SyncDescriptor<T> {
readonly ctor: any;
readonly staticArguments: any[];
readonly supportsDelayedInstantiation: boolean;
constructor(ctor: new (...args: any[]) => T, staticArguments: any[] = [], supportsDelayedInstantiation: boolean = false) {
this.ctor = ctor;
this.staticArguments = staticArguments;
this.supportsDelayedInstantiation = supportsDelayedInstantiation;
}
}

接下来,main.ts的startup方法内,就实例化了这些服务

			await instantiationService.invokeFunction(async accessor => {
const environmentService = accessor.get(IEnvironmentService);
const configurationService = accessor.get(IConfigurationService);
const stateService = accessor.get(IStateService);
try {
await this.initServices(environmentService, configurationService as ConfigurationService, stateService as StateService);
} catch (error) { // Show a dialog for errors that can be resolved by the user
this.handleStartupDataDirError(environmentService, error); throw error;
}
});

这里accessor的get方法如下:(src\vs\platform\instantiation\common\instantiationService.ts)

				get: <T>(id: ServiceIdentifier<T>, isOptional?: typeof optional) => {

					if (_done) {
throw illegalState('service accessor is only valid during the invocation of its target method');
} const result = this._getOrCreateServiceInstance(id, _trace);
if (!result && isOptional !== optional) {
throw new Error(`[invokeFunction] unknown service '${id}'`);
}
return result;
}

有个_getOrCreateServiceInstance方法:

	private _getOrCreateServiceInstance<T>(id: ServiceIdentifier<T>, _trace: Trace): T {
let thing = this._getServiceInstanceOrDescriptor(id);
if (thing instanceof SyncDescriptor) {
return this._createAndCacheServiceInstance(id, thing, _trace.branch(id, true));
} else {
_trace.branch(id, false);
return thing;
}
}

你发现,如果它想获取的对象是SyncDescriptor类型的,就会创建并缓存相应的对象
这个方法_createAndCacheServiceInstance负责创建对象的实例(暂时先不解释)
下次获取这个对象的时候,就直接从缓存中获取了

最新文章

  1. AngularJS快速入门指南12:模块
  2. 【POJ 1698】Alice&#39;s Chance(二分图多重匹配)
  3. 为什么要在block用weak self
  4. _x、__x、__x__含义与区别
  5. 【avalon】offsetParent
  6. 【LeetCode】223 - Rectangle Area
  7. activity切换时的overridePendingTransition动画效
  8. javaweb学习总结二十二(servlet开发中常见的问题汇总)
  9. oracle的sqlnet.ora , tnsnames.ora , Listener.ora 文件的作用(转)
  10. HTML5新增的拖放API---(一)
  11. 左右 Java 于 finally 深度分析语句块
  12. linux_操作系统
  13. Google Bigtable (中文版)
  14. webpack的常识概念
  15. 【php】 php获取文件路径中的文件名和文件后缀方法
  16. Codeforces Round #436 (Div. 2)C. Bus 模拟
  17. spark aggregate函数详解
  18. Git学习(一)(2015年11月12日)
  19. OAF 中下载使用XML Publisher下载PDF附件
  20. reac——父组件向子组件传递值,子组件何时能同步获得父组件改变后的值

热门文章

  1. npm 使用过程中报错问题-及npm使用
  2. mysql初始化/usr/local/mysql/bin/mysqld: error while loading shared libraries: libnuma.so.1: cannot open shared object file: No such file or directory
  3. 初学Elasticsearch
  4. unittest---unittest的几种执行方法
  5. laravel实现多模块
  6. CountDownLatch原理分析
  7. PAT 1013 Battle Over Cities DFS深搜
  8. Django入门必知必会操作
  9. 【重拾基础】耐人寻味的CSS属性white-space
  10. 从七个方面,面试BAT大厂高级工程师,纯干货!