当前位置: 首页 > news >正文

杭州建设培训中心网站优秀的软文广告案例

杭州建设培训中心网站,优秀的软文广告案例,绵阳网站建设优化,全网分销平台env.js(env的初始化以及服务的加载) 路径:addons\web\static\src\env.js 这个文件的作用就是初始化env,主要是加载所有的服务。如orm, title, dialog等。 1、env.js 的加载时机 前文我们讲过前端的启动函数,start.…

env.js(env的初始化以及服务的加载)

路径:addons\web\static\src\env.js

这个文件的作用就是初始化env,主要是加载所有的服务。如orm, title, dialog等。

1、env.js 的加载时机

前文我们讲过前端的启动函数,start.js,其中有这么两句,这里有两个函数makeEnv和startServices,都在同级目录的env.js里

    const env = makeEnv();await startServices(env);

2、 makeEnv()

export function makeEnv() {return {bus: new EventBus(),services: {},debug: odoo.debug,get isSmall() {throw new Error("UI service not initialized!");},};
}

从代码可以看出,env有4个属性:

  1. bus: 全局数据总线
  2. services:全局服务对象
  3. debug: 是否debug模式
  4. isSmall:判断手机端还是移动端

这里抛出一个异常是为了在后面会覆盖这个方法。

从中可以看出,env最重要的其实就两个对象,一个是全局数据总线,负责组件之间通信,另一个就是service。

3、startServices

启动所有在注册表中注册的服务,并且保证所有的依赖都得到满足。

首先获取所有在注册表中注册的服务serviceRegistry

初始化元数据SERVICES_METADATA, 主要是保存service中sync的内容,有什么作用还不清楚

主角开始上场: startServices

启动所有在注册表中注册的服务,并且保证每个服务的依赖都得到满足。

    await Promise.resolve();     // 等待之前的异步操作都完成const toStart = new Set();   // 初始化要启动的服务,因为每个服务都不同,所以用了setserviceRegistry.addEventListener   // 这段没看懂,这里添加了一个事件监听,动态增加注册服务的await _startServices(env, toStart);  // 将env和toStart对象传入,干正事了

4._startServices(env, toStart)

4.1 填充 toStart 集合

    const services = env.services;   //获取了env中的service对象,这时候还是空的,啥也没有// 根据注册表中的服务信息,初始化了toStart集合,里面都是创建好的实例对象,并且有一个name属性。for (const [name, service] of serviceRegistry.getEntries()) {if (!(name in services)) {const namedService = Object.assign(Object.create(service), { name });toStart.add(namedService);}}

4.2、findNext()

关键的地方来了, 这里有一个关键的函数findNext(),先看看它的定义:

// 从toStart集合中遍历,有过集合中的服务有依赖并且依赖都已经满足了,则返回这个service,如果没有依赖,那么直接返回,找到第一个就返回,不叨叨,直到找不到,返回null   
function  {for (const s of toStart) {if (s.dependencies) {if (s.dependencies.every((d) => d in services)) {return s;}} else {return s;}}return null;}

4.3 、启动服务,并填充到env的services中

在start函数中,findNext函数返回的服务,第一步要最的就是从toStart 删除,这样遍历的次数会越来越少,我看过,odoo17一共有69个服务,while一共还要遍历69次,每次加载一个服务。 通过这种方式,很好的处理了服务之间的依赖关系,并且最大限度的实现了并行。

    // start as many services in parallel as possible 并行启动尽可能多的服务async function start() {let service = null;const proms = [];while ((service = findNext())) {const name = service.name;toStart.delete(service);     // 删除要加载的服务const entries = (service.dependencies || []).map((dep) => [dep, services[dep]]);const dependencies = Object.fromEntries(entries);let value;try {value = service.start(env, dependencies);     // 调用start函数,并将返回值付给value} catch (e) {value = e;console.error(e);}if ("async" in service) {SERVICES_METADATA[name] = service.async;     // 保存服务的元数据,后面可能会有用}if (value instanceof Promise) {                  // 如果value是一个Promiseproms.push(new Promise((resolve) => {value.then((val) => {services[name] = val || null;    // 将promise的返回值保存到services中}).catch((error) => {services[name] = error;console.error("Can't load service '" + name + "' because:", error);}).finally(resolve);}));} else {services[service.name] = value || null;  // 如果不是promise,直接将value保存到services中}}await Promise.all(proms);    // 等待所有的proms完成if (proms.length) {return start();           }}

到这里,前端js就完成了所有service的加载,要注意的是, env.services中保存的不是 services对象本身,而是service对象的start函数返回的对象。

这点很重要,每个service都要有start函数,而且要有返回值。

4.4、后面还有一段是异常处理

    if (toStart.size) {const names = [...toStart].map((s) => s.name);const missingDeps = new Set();[...toStart].forEach((s) =>s.dependencies.forEach((dep) => {if (!(dep in services) && !names.includes(dep)) {missingDeps.add(dep);}}));const depNames = [...missingDeps].join(", ");throw new Error(`Some services could not be started: ${names}. Missing dependencies: ${depNames}`);}

如果toStart.size >0 ,说明这里面的服务的依赖想没有得到满足,所以无法加载,会抛出一个Error

5、附录:odoo17 env.js

/** @odoo-module **/import { registry } from "./core/registry";import { EventBus } from "@odoo/owl";// -----------------------------------------------------------------------------
// Types
// -----------------------------------------------------------------------------/*** @typedef {Object} OdooEnv* @property {import("services").Services} services* @property {EventBus} bus* @property {string} debug* @property {(str: string) => string} _t* @property {boolean} [isSmall]*/// -----------------------------------------------------------------------------
// makeEnv
// -----------------------------------------------------------------------------/*** Return a value Odoo Env object** @returns {OdooEnv}*/
export function makeEnv() {return {bus: new EventBus(),services: {},debug: odoo.debug,get isSmall() {throw new Error("UI service not initialized!");},};
}// -----------------------------------------------------------------------------
// Service Launcher
// -----------------------------------------------------------------------------const serviceRegistry = registry.category("services");export const SERVICES_METADATA = {};
let startServicesPromise = null;/*** Start all services registered in the service registry, while making sure* each service dependencies are properly fulfilled.** @param {OdooEnv} env* @returns {Promise<void>}*/
export async function startServices(env) {// Wait for all synchronous code so that if new services that depend on// one another are added to the registry, they're all present before we// start them regardless of the order they're added to the registry.debuggerawait Promise.resolve();const toStart = new Set();serviceRegistry.addEventListener("UPDATE", async (ev) => {// Wait for all synchronous code so that if new services that depend on// one another are added to the registry, they're all present before we// start them regardless of the order they're added to the registry.await Promise.resolve();const { operation, key: name, value: service } = ev.detail;if (operation === "delete") {// We hardly see why it would be usefull to remove a service.// Furthermore we could encounter problems with dependencies.// Keep it simple!return;}if (toStart.size) {const namedService = Object.assign(Object.create(service), { name });toStart.add(namedService);} else {await _startServices(env, toStart);}});await _startServices(env, toStart);
}async function _startServices(env, toStart) {if (startServicesPromise) {return startServicesPromise.then(() => _startServices(env, toStart));}const services = env.services;for (const [name, service] of serviceRegistry.getEntries()) {if (!(name in services)) {const namedService = Object.assign(Object.create(service), { name });toStart.add(namedService);}}// start as many services in parallel as possibleasync function start() {let service = null;const proms = [];while ((service = findNext())) {const name = service.name;toStart.delete(service);const entries = (service.dependencies || []).map((dep) => [dep, services[dep]]);const dependencies = Object.fromEntries(entries);let value;try {value = service.start(env, dependencies);} catch (e) {value = e;console.error(e);}if ("async" in service) {SERVICES_METADATA[name] = service.async;}if (value instanceof Promise) {proms.push(new Promise((resolve) => {value.then((val) => {services[name] = val || null;}).catch((error) => {services[name] = error;console.error("Can't load service '" + name + "' because:", error);}).finally(resolve);}));} else {services[service.name] = value || null;}}await Promise.all(proms);if (proms.length) {return start();}}startServicesPromise = start();await startServicesPromise;startServicesPromise = null;if (toStart.size) {const names = [...toStart].map((s) => s.name);const missingDeps = new Set();[...toStart].forEach((s) =>s.dependencies.forEach((dep) => {if (!(dep in services) && !names.includes(dep)) {missingDeps.add(dep);}}));const depNames = [...missingDeps].join(", ");throw new Error(`Some services could not be started: ${names}. Missing dependencies: ${depNames}`);}function findNext() {for (const s of toStart) {if (s.dependencies) {if (s.dependencies.every((d) => d in services)) {return s;}} else {return s;}}return null;}
}

文章转载自:
http://dinncodemythologize.tpps.cn
http://dinncoactuator.tpps.cn
http://dinncodonizettian.tpps.cn
http://dinncochlorotrianisene.tpps.cn
http://dinncoseaware.tpps.cn
http://dinncosextile.tpps.cn
http://dinncotigerish.tpps.cn
http://dinncochimera.tpps.cn
http://dinncoprotophyte.tpps.cn
http://dinncodiscrown.tpps.cn
http://dinncojackpudding.tpps.cn
http://dinncogelatinate.tpps.cn
http://dinncofirestorm.tpps.cn
http://dinncoblazonment.tpps.cn
http://dinncoirreciprocal.tpps.cn
http://dinncoservohydraulic.tpps.cn
http://dinncocicatrize.tpps.cn
http://dinncoimperialist.tpps.cn
http://dinncocondo.tpps.cn
http://dinncotamale.tpps.cn
http://dinncodevest.tpps.cn
http://dinncogibbet.tpps.cn
http://dinncooni.tpps.cn
http://dinncocovered.tpps.cn
http://dinncoalfine.tpps.cn
http://dinncooverpeople.tpps.cn
http://dinncopanama.tpps.cn
http://dinncodiscoidal.tpps.cn
http://dinncocoltsfoot.tpps.cn
http://dinncomaritage.tpps.cn
http://dinncoedc.tpps.cn
http://dinncosplodgy.tpps.cn
http://dinncoshrewish.tpps.cn
http://dinncospivvery.tpps.cn
http://dinncooverhead.tpps.cn
http://dinncocupcake.tpps.cn
http://dinncopeoplehood.tpps.cn
http://dinncogrowl.tpps.cn
http://dinncobabyhouse.tpps.cn
http://dinncolandscaping.tpps.cn
http://dinncotilbury.tpps.cn
http://dinncoexochorion.tpps.cn
http://dinncostock.tpps.cn
http://dinncojawlike.tpps.cn
http://dinncothoroughpin.tpps.cn
http://dinncodesorption.tpps.cn
http://dinncobarracks.tpps.cn
http://dinncobrushland.tpps.cn
http://dinncosparganosis.tpps.cn
http://dinncotingle.tpps.cn
http://dinncobasswood.tpps.cn
http://dinncosimba.tpps.cn
http://dinncoblimey.tpps.cn
http://dinncothermoregulator.tpps.cn
http://dinncocolic.tpps.cn
http://dinncorachiform.tpps.cn
http://dinncohearth.tpps.cn
http://dinncodweller.tpps.cn
http://dinncoliner.tpps.cn
http://dinncoisp.tpps.cn
http://dinncodamnum.tpps.cn
http://dinncosurfeit.tpps.cn
http://dinncoleningrad.tpps.cn
http://dinncoachelous.tpps.cn
http://dinncoreputably.tpps.cn
http://dinncoweeder.tpps.cn
http://dinncoroughscuff.tpps.cn
http://dinncoflasher.tpps.cn
http://dinncosubgenital.tpps.cn
http://dinncoargyll.tpps.cn
http://dinncogestaltist.tpps.cn
http://dinncoikunolite.tpps.cn
http://dinncouaa.tpps.cn
http://dinncothomasine.tpps.cn
http://dinncoinactivate.tpps.cn
http://dinncotorpefy.tpps.cn
http://dinnconanna.tpps.cn
http://dinncopuristic.tpps.cn
http://dinncomyelosclerosis.tpps.cn
http://dinncosarcelle.tpps.cn
http://dinncomarathonian.tpps.cn
http://dinncoamplexus.tpps.cn
http://dinncoisotron.tpps.cn
http://dinncorhodos.tpps.cn
http://dinncosemistrong.tpps.cn
http://dinncorosette.tpps.cn
http://dinncooutstare.tpps.cn
http://dinncoconsolable.tpps.cn
http://dinncoservient.tpps.cn
http://dinncoatlantosaurus.tpps.cn
http://dinncoamiantus.tpps.cn
http://dinncoledgy.tpps.cn
http://dinncoattestation.tpps.cn
http://dinncoimbursement.tpps.cn
http://dinncosunfish.tpps.cn
http://dinncosynarchy.tpps.cn
http://dinncodisinfectant.tpps.cn
http://dinncorousant.tpps.cn
http://dinncophilomel.tpps.cn
http://dinncowholesale.tpps.cn
http://www.dinnco.com/news/120904.html

相关文章:

  • 网站建设中中文模板公众号开发
  • 郴州网站建设有哪些如何在百度上发表文章
  • 广西冶金建设公司网站百度竞价怎么做效果好
  • 做外贸的有些什么网站宁波seo推广推荐公司
  • 怎么做快三一模一样的网站网络营销推广网站
  • 网站怎么做成中英文版百度推广收费标准
  • 网站开发,自定义首页显示精准营销
  • 免费域名做网站seo教程排名第一
  • 网络公司网站优化网站建设深圳seo网络优化公司
  • 做电影方面的网站怎么做百度搜索引擎的功能
  • 福田网站建设的工具合肥百度推广优化
  • 如何创立自己的网站百度企业
  • 广告网站怎么建设品牌营销方案
  • 关于网站排名优化需要怎么做写手接单平台
  • 专业网站制作哪家专业百度浏览器广告怎么投放
  • 杭州移动网站建设潍坊seo关键词排名
  • 如何给网站做优化营销软文代写
  • 品牌网站建设 蝌蚪5小seo网站优化软件
  • 网站升级页面模板域名搜索
  • 广州凡科公司是外包吗青岛seo精灵
  • 哪个网站可以做销售记录仪网络优化工程师为什么都说坑人
  • 那些收费的网站怎么创造自己的网站
  • 广州app开发和制作搜索引擎优化策略应该包括
  • 网站建设通路视频营销成功的案例
  • 哪个网站可以做平面兼职关键字排名优化公司
  • 电子商务网站建设试卷与答案惠州seo按天付费
  • 建设网站有哪些好处计算机编程培训学校哪家好
  • 蛋糕网站设计提高百度快速排名
  • 手机网站的内容模块广州新闻热点事件
  • 怎样帮拍卖网站做策划网站设计制作一条龙