第十三章 依赖注入(DI)
注:学习使用,禁止转载
通常,随着应用程序的变大,应用程序的不同部分需要交流,当模块a需要模块b才能运行时,我们说b依赖于a。
获得依赖的最常见的一种方式就是导入一个文件,比如,在我们假设的模块中,我们可能向下面这样做:
// in A.ts
import {B} from 'B'; // a dependency!B.foo(); // using B
通常情况下,简单导入其他代码就够了,然而有时候,我们所需要的是一种更复杂的方式提供依赖项。比如:
- 在测试期间,我们需要实现B代替MockB。
- 我们想要分享我们B类的单例在我们的app中(比如单例模式)
- 当每次b被使用时,需要创建一个新的实例
DI可以解决这些问题
DI是这样一个系统,它使我们程序的一部分可以访问其他部分,而且,我们可以配置这些事怎么发生的。
DI这个词是用来描述设计模式的(它使用在很多框架中),angular内建就实现了DI。
使用DI的主要好处是,客户组件不需要了解如何创建依赖,只需要知道怎么交互就可以了。4
DI的例子:PriceService
想象一下,我们有一个Product类,这个Product有一个价格,为了计算这个产品的最终价格,我们依赖于一个服务,它使用输入传递进来。
- 产品的基本价格
- 我们销售的状态
下面是不使用DI的样式:
class Product {constructor(basePrice: number) {this.service = new PriceService();this.basePrice = basePrice;}price(state: string) {return this.service.calculate(this.basePrice, state);}
}
现在,让我们想象一下,我们需要为这个Product编写一个测试,假设PriceService通过查询数据库返回一个折扣,我们写的测试像下面这样:
let product;beforeEach(() => {product = new Product(11);});describe('price', () => {it('is calculated based on the basePrice and the state', () => {expect(product.price('FL')).toBe(11.66);});
})
即使这个测试可以工作,这种方法有一些缺点,为了测试成功,必须有几个条件得到满足:
- 数据库必须运行
- Florida的税收收入必须是我们期望的。
基本上,如果我们增加一个意想不到的依赖,我们的测试会更加脆弱。
如果我们做一点改变,像下面这样:
class Product {constructor(service: PriceService, basePrice: number) {this.service = service;this.basePrice = basePrice;}price(state: string) {return this.service.calculate(this.basePrice, state);}
}
现在,创建一个Product,客户需要决定使用哪一种价格服务。
我们可以编写一个简单的测试,如下:
class MockPriceService {calculate(basePrice: number, state: string) {if (state === 'FL') {return basePrice * 1.06;}return basePrice;}
}
通过这个小小的改变,我们可以调整我们的测试使其更清楚,而且摆脱了数据的依赖。
let product;beforeEach(() => {const service = new MockPriceService();product = new Product(service, 11);});describe('price', () => {it('is calculated based on the basePrice and the state', () => {expect(product.price('FL')).toBe(11.66);});
})
我们还会得到好处,我们的 Product类是隔离的,也就是说,我们的Product有一个确切的依赖。
Don’t Call Us…”别叫我
DI这个技术依赖于控制反转这种原则。
多年来,这是很常见的的模式,我们为每一个组件注明完整的应用程序上下文,并且设置它的依赖,这看起来是很清晰的,Product类必须知道PriceService类。
这样做的一个缺点是,一旦一个组件需要一个依赖,组件本身变得脆弱而且难以改变。如果我们做出变化,我们的组件依赖于很多其他组件,我们不得不传播这些依赖。换句话说,它使得我们的组件紧耦合。
当我们使用DI的时候,我们朝着松耦合的方向前进,单个应用程序尽量少影响其他的组件。并且,只要这些组件的接口没有改变,我们甚至可以直接改变它们,不需要组件做任何其他的改变。
ng2继承了ng1的一大特点就是控制反转。angular使用DI去解决来自于外部的依赖。
传统上,如果组件a依赖组件b,那么在组件a的内部会创建一个b的对象,这意味着a依赖于b,
angular使用DI改变这个事情,A像依赖注入系统请求B,依赖注入系统会像我们期望一样传递一个B给A。
相对传统方式来说,这个有很多好处。一个好处就是当我们测试A的时候,我们可以mock一个B出来注入到A。
在这本书中,我们使用了很多次DI。比如我们在路由那张创建music应用的时候,为了去和Spotify API进行交互,我们创建了SpotifyService,它被注入到了几个组件中:
code/routes/music/app/ts/components/AlbumComponent.ts
constructor(public routeParams: RouteParams, public spotify: SpotifyService,public locationStrategy: LocationStrategy) {this.id = routeParams.get('id');
现在,让我们学习怎么创建自己的service和我们注入它们的不同形式。
依赖注入部分
注册一个依赖,我们必须将其绑定到能标识依赖的地方,这个标识被称为依赖令牌(token),比如,我们想要注册一个API的URL,我们可以使用API_URL作为令牌,同理,如果我们注册一个类,我们可以使用类本身作为它的令牌。
在angular中的依赖注入,分为三步部分:
- 提供者(Provider-通常也称为绑定)映射一个令牌(通常是一个string或者一个类)到一个列表中,它告诉angular,怎么去创建一个对象,并且给定一个令牌。
- 注入器(Injector),它存储绑定的集合,并在创建对象的时候去解析依赖并且注入它们
- 依赖(Dependency),将被注入的东西
我们可以通过下面这张图描述它们的职责:
当处理DI的时候,有很多不同的选择,让我们逐一学习它们。
使用DI最通用的场景就是在整个应用程序中提供服务或者值,这个场景占了99%。
这个就是我们想要去做的,接下来,我们会讲解怎样编写一个基本的服务,它会是我们在用户程序中花费时间最多的。
注入器
像上面提到的一样,angular在后台为我们安装一个DI,在我们使用注解注入依赖到我们的组件之前,让我们首先了解一下注入器。
我们创建一个仅仅返回一个string的简单服务。
code/dependency_injection/simple/app/ts/app.ts
class MyService {getValue():string{return 'a value';}
}
接下来,我们创建我们的APP组件:
code/dependency_injection/simple/app/ts/app.ts
@Component({selector: 'di-sample-app',template: `<button (click)="invokeApi()">Get a value</button>`
})
class DiSampleApp {myService: MyService;constructor() {let injector: any = ReflectiveInjector.resolveAndCreate([MyService]);this.myService = injector.get(MyService);console.log('Same instance?', this.myService === injector.get(MyService));}invokeApi():void {console.log('MyService returned', this.myService.getValue());}
}
这个程序很简单,我们定义一个DiSampleApp的组件,它会显示一个button,当button被点击的时候,调用invokeApi。
现在,我们关注一下构造函数,我们使用一个来自于ReflectiveInjector的静态方法resolveAndCreate.这个方法的职责是创建一个新的注入器,参数是一个我们想要这个注入器知道的可注入的(injectable)东西的数组,在这个例子中,我只想要它知道MyService。
ReflectiveInjector是Injector的具体实现,它使用反射去寻找合适的参数类型,相对于其他的注入器,ReflectiveInjector是一个通用的注入器。
一个重要的事情是,它将会注入这个类的单实例(single)
这个可以通过构造函数的最后两行得以确定,
console.log('Same instance?', this.myService === injector.get(MyService));
这句话证明,我们使用injector.get获取的两次实例是相同的。
注意,如果我们使用自己的注入器,我们就不需要告诉应用程序的可注入列表。
既然我们学会了注入器的工作原理,然后我们学习angular的注入框架,接下来学习我们可以注入的其他东西,并且学会怎么注入它们。
Providers(提供者)
接下来需要知道的,在angular的DI系统中,我们可以使用几种注入方式:
- 注入一个单例
- 调用任何函数,然后注入这个函数的返回值
- 注入一个值
- 创建一个别名
让我们分开看看
使用一个类
注入一个类的单实例可能是最通常做的事情。下面是我们配置它的代码:
provide(MyComponent, {useClass: MyComponent})
值得注意的是,provide方法接收两个参数,第一个就是令牌,第二个是怎样注入或者注入什么。所以这里,我们将我们的MyComponent类映射到MyComponent令牌,在这种情况下,类的名字与令牌匹配,这是通常的情形,但是要注意,被注入的东西和令牌不一定要有相同的名字。
就像我们在上面看到的一样,这个方法会创建一个单例对象,并且我们每次注入的时候它都返回这个相同的单例,当然,在第一次注入之前,不会创建这个类的实例,所以第一次注入的时候,会调用该类的构造函数。
如果一个服务的构造函数需要参数怎么办呢?
code/dependency_injection/misc/app/ts/app.ts
class ParamService {constructor(private phrase: string) {console.log('ParamService is being created with phrase', phrase);}getValue(): string {return this.phrase;}
}
注意,这个构造器怎么获取参数呢?如果我们使用正常的注入机制:
bootstrap(MyApp, [ParameterService]);
我们会得到一个错误:
这个发生的原因是我们没有给注入器关于构建一个类的足够的信息,为了解决这个问题,我们需要告诉注入器,当创建这个服务的实例时,我们想要它去使用哪些参数。
如果我们希望创建服务的时候传递参数,我们可能需要使用工厂来代替(factory)
工厂(Using a Factory)
当我们使用一个工厂注入器的时候,我们可以编写一个函数,这个函数可以返回任何类型。
provide(MyComponent, useFactory: () => {if (loggedIn) {return new MyLoggedComponent();}return new MyComponent();
});
在上面的代码中,我们注入MyComponent令牌,但是这个会检测一个外部变量loggedIn,如果这个参数为真,我们会接受一个MyLoggedComponent的实例,否则返回MyComponent。
工厂也可以有依赖,比如:
provide(MyComponent, useFactory: (user) => {if (user.loggedIn()) {return new MyLoggedComponent(user);}return new MyComponent();
}, deps: [User])
如果我们希望像上面一样使用我们的ParamService,我们可以将他包装在useFactory中,像下面这样:
bootstrap(DiSampleApp, [SimpleService,provide(ParamService, {useFactory: (): ParamService => new ParamService('YOLO')})
]).catch((err: any) => console.error(err));
对于创建注入来说,工厂是功能最强大的方式,因为我们可以在函数中做任何事情。
使用一个值
当我们想要一个值,在应用程序的另外一个地方会被重定义的时候,注入一个值是非常有用的。比如:
provide('API_URL', {useValue: 'http://my.api.com/v1'})
用于定义别名(alias)
我们也可以用于定义一个引用的别名,像下面这样:
provide(NewComponent, {useClass: MyComponent})
在应用程序中的依赖注入
在编写应用程序时,为了注入服务,需要执行下面三步:
- 创建一个服务类
- 在接收组件里面声明一个依赖
- 配置注入(使用angular注册一个注入)
我们要做的第一件事情就是创建一个服务类,这个类可以暴露一些我们希望的行为,这个被称为注射,它包含一些我们组件类将要从诸如服务那里获取到的行为。
下面是我们创建的一个服务:
code/dependency_injection/simple/app/ts/services/ApiService.ts
export class ApiService {get(): void {console.log('Getting resource...');}
}
现在,我们有了要注入的类,接下来就是在我们的组件中声明一个依赖,前面我们直接使用Injector类,但是angular为我们提供了两种简便的方式,最经典的方式就是在我们的构造器中声明。
为了做这个事情,首先需要引入服务:
code/dependency_injection/simple/app/ts/app.ts
/** Services*/
import {ApiService} from 'services/ApiService';
然后,我们在构造器中声明它:
code/dependency_injection/simple/app/ts/app.ts
class DiSampleApp {constructor(private apiService:ApiService) {}
当我们在构造器中声明之后,angular会通过反射查找要注入的服务,并注入进来。也就是说,angular会通过我们在构造器中声明的对象类型寻找ApiService,然后向DI系统接收一个合适的注入。
有时,我们需要给angular更多的提示,这个时候,我们使用@Inject注解。
class DiSampleApp {private apiService: ApiService;constructor(@Inject(ApiService) apiService) {this.apiService = apiService;
}
使用依赖注入的最后一件事情就是使用injectable链接我们组件想要的注入的东西。换句话说,我们要告诉angular当一个组件声明它的依赖的时候,哪些东西需要注入。
provide(ApiService, {useClass: ApiService})
在上面的代码中,我们使用ApiService这个token去导出ApiService的单实例。
与Injectors工作
我们已经可以使用injectors做一些事情,现在我们讨论,我们什么时候需要显示使用他们
一种情况就是当我们希望控制依赖注入的单实例创建的时候,为了描述这个情况,我们使用ApiService创建另外一个应用程序。
这个服务会使用到其他的两个服务,它是基于浏览器视框。当小于800像素的时候,返回一个叫着SmallService,否则,返回一个LargeService.。
SmallService像下面这样:
code/dependency_injection/complex/app/ts/services/SmallService.ts
export class SmallService {run(): void {console.log('Small service...');}
}
LargeService:像这样:
code/dependency_injection/complex/app/ts/services/LargeService.ts
export class LargeService {run(): void {console.log('Large service...');}
}
然后,我们编写ViewPortService,它选择两者之一:
code/dependency_injection/complex/app/ts/services/ViewPortService.ts
import {LargeService} from './LargeService';
import {SmallService} from './SmallService';export class ViewPortService {determineService(): any {let w: number = Math.max(document.documentElement.clientWidth,window.innerWidth || 0);if (w < 800) {return new SmallService();}return new LargeService();}
}
现在,让我们创建一个访问我们服务的APP,
code/dependency_injection/complex/app/ts/app.ts
class DiSampleApp {constructor(private apiService: ApiService,@Inject('ApiServiceAlias') private aliasService: ApiService,@Inject('SizeService') private sizeService: any) {}
这里,我们获取了一个ApiService的实例,但是我们又获取了一个ApiService的服务,并给它取一个别名ApiServiceAlias,然后,我们获取一个SizeService,但是它还没有定义。
为了理解每一个service代表什么,让我们看看bootstrap的代码:
bootstrap(DiSampleApp, [ApiService,ViewPortService,provide('ApiServiceAlias', {useExisting: ApiService}),provide('SizeService', {useFactory: (viewport: any) => {return viewport.determineService();}, deps: [ViewPortService]})
]).catch((err: any) => console.error(err));
这里,我们希望应用程序注入器知道ApiService和ViewPortService。然后,我们定义了ApiService的另外一个别名ApiServiceAlias。然后,我们定义了另外一个注入叫着SizeService.这个工厂接收一个ViewPortService的实例,将它作为依赖放入列表,然后调用它的determineService,它会根据浏览器的宽度返回SmallService或者LargeService。
当我们在app上点击button的时候,我们希望去做三个调用: 一个是ApiService,一个是ApiServiceAlias,一个是SizeService:。
code/dependency_injection/complex/app/ts/app.ts
invokeApi(): void {this.apiService.get();this.aliasService.get();this.sizeService.run();}
现在,让我们运行我们的app,如果在小的浏览器上:
如果在大的浏览器上:
可以看到,两次打印的信息不一样,说明获取到了不同的服务。
但是,现在,如果我们缩放浏览器,并点击button,它始终会打印Large。
这是因为,factory只会被调用一次,为了解决这个问题,我们创建我们自己的注入器,它获取适当的服务,像下面这样:
code/dependency_injection/complex/app/ts/app.ts
let injector:any = ReflectiveInjector.resolveAndCreate([ViewPortService,provide('OtherSizeService', {useFactory: (viewport:any) => {return viewport.determineService();}, deps: [ViewPortService]})]);let sizeService:any = injector.get('OtherSizeService');sizeService.run();
这里,我们创建一个注入器,它知道ViewPortService,和另外的OtherSizeService作为令牌的注入,最后我们使用获取OtherSizeService的实例。现在如果我们缩放窗口,点击button,我们会得到合适的日志,因为每次点击button的时候,都会调用useInjectors一次。
替换值
使用DI的另一个原因就是在运行时替换值。当我们有一个APIService,它执行HTPP请求的时候发生。在我们的单元测试或者继承测试中,我们不希望我们的代码访问数据库,在这种情况下,我们希望编写一个mock service来代替我们的真正实现。
比如,如果我们希望在开发环境和生产环境,我们的APP访问不同的api。
或者是,当我们发布一个开源或者可重用的API服务时,我们希望客户端应用程序定义或者重载我们API URL。
让我们编写一个应用程序,它根据我们是在开发环境还是在生产环境返回不同的值。
code/dependency_injection/value/app/ts/services/ApiService.ts
import { Inject } from '@angular/core';export const API_URL: string = 'API_URL';export class ApiService {constructor(@Inject(API_URL) private apiUrl: string) {}get(): void {console.log(`Calling ${this.apiUrl}/endpoint...`);}
}
我们定义一个常量,它会被作为令牌为API URL的依赖使用。换句话说,angular会使用API URL来存储调用的URL信息,这样,当我们使用@Inject(API_URL)的时候,就会返回合适的值,注意,我们导出了API_URL常量,所以客户端应用程序可以使用。
现在,已经有了service,让我们编写一个使用这个服务的组件,它根据不同的运行环境提供不同的值。
code/dependency_injection/value/app/ts/app.ts
@Component({selector: 'di-value-app',template: `<button (click)="invokeApi()">Invoke API</button>`
})
class DiValueApp {constructor(private apiService: ApiService) {}invokeApi(): void {this.apiService.get();}
}
这是组件的代码,在构造器中,我们使用了注入apiService服务,如果想要显示声明,可以使用下面这种方式:
constructor(@Inject(ApiService) private apiService: ApiService) { }
在这个组件中有一个button,当我们点击button的时候,调用apiService的get方法,并打印返回值,也就是API_URL的值。
接下来是使用providers配置应用程序。
code/dependency_injection/value/app/ts/app.ts
bootstrap(DiValueApp, [provide(ApiService, { useClass: ApiService }),provide(API_URL, {useValue: isProduction ?'https://production-api.sample.com' :'http://dev-api.sample.com'})
]).catch((err: any) => console.error(err));
首先,我们声明一个常量isProduction,并且设置它为false,我们可以假装我们做一些事情来决定我们是不是在生产环境。这个设置可以是像我们一样硬编码,也可以使用像webpack一样的设置。
最后,我们启动应用程序,并且按照两个提供程序,一个是ApiService,另外一个是API_URL,如果我们是在生产环境中,我们会使用一个值,否则使用另外一个值。
为了测试,可以将isProduction设置为true,并且点击button,会得到下面两种输出。
总结
就像你所看到的,管理应用程序依赖方面,DI是一个功能强大的方式。
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 双眼皮下至
...
2024/4/21 15:07:45 - 双眼皮消肿慢怎么办
...
2024/4/21 15:07:44 - 上海9院 割割双眼皮搽红霉素眼膏
...
2024/4/21 15:07:43 - 浅谈前端测试
前端测试或许被好多人误解,也许大家更加倾向于编写面向后端的测试,逻辑性强,测试方便等 聊到这导致了好多前端从来不写测试(测试全靠手点~~~) 其实没必要达到测试驱动开发的程度&…...
2024/4/21 15:07:41 - 韩雪双眼皮是做的吧
...
2024/4/21 15:07:41 - 面相 35到40岁 北京袁渊双眼皮 隐
...
2024/4/21 15:07:39 - Angular @ViewChild @ViewChildren @ContentChild @ContentChildren 之间的区别
Angular ViewChild ViewChildren ContentChild ContentChildren 之间的区别 1.何时使用ViewChild和ViewChildren 当在写一个组件时,如果明确template中把其他组件放置上去,这个时候就可以使用ViewChild(XXXComponent) componet:Componet 或者 ViewChil…...
2024/4/21 15:07:40 - angular组件开发之-ng-content,contentChild,ng-container,ng-templeate,viewChild详解-第二篇
contentChild 上一篇,我们讲了ng-content的用法,angular提供了contentChild来获取ng-content里面的内容, ContentChild装饰器(selector); selector:组件名字或者模板变量,不能是简单的div、img这种原始标签! 接着上…...
2024/4/21 15:07:37 - Angular 插槽内容投影的使用(二)
Angular 插槽内容投影的使用(一) ng-content 注意事项 ng-content标签不会“产生”内容,只是投影现有的内容,可以理解为移动现有的内容到指定位置,不会对现有的内容进行销毁和重建。 验证步骤: 我们定义…...
2024/4/21 15:07:37 - Angular自学笔记(?)ContentChild和ContentChildren
ContentChild 用法类似ViewChild, 获取投影中到组件或指令还有元素dom等 获取投影中但组件 import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from @angular/core;@Component({selector: app-content-child-panel,templateUrl...
2024/4/21 15:07:35 - 突然有了罗敏双眼皮全切
...
2024/4/21 15:07:36 - 金华华美双眼皮多少钱
...
2024/4/22 17:54:03 - angular学习日志05 显示文本 ng-bind
方法1: <p>{{helloworld}}</p> 方法2: <p ng-bind"helloworld"></p> 两种方法是等量的,如果对于页面要求比较高 建议使用第二种方法展示数据...
2024/4/23 12:36:51 - 用户行为日志分析
用户行为日志生成渠道:Nginx,Ajax 记录用户访问行为日志的原因:网站页面的访问量网站的黏性推荐 用户行为日志内容:1.访问的系统属性:操作系统,浏览器等等 2.访问特征:点击URL,从哪个…...
2024/4/20 15:05:32 - 割双眼皮后吃鸡蛋
...
2024/4/20 15:05:32 - 割完双眼皮能玩手机吗
...
2024/4/20 15:05:30 - 韩式压双眼皮王者艺星
...
2024/4/20 15:05:29 - 微信小程序之 文件类型和项目结构
我们之前文章中简单介绍了一下微信小程序的项目结构和配置,现在我们来详细介绍一下具体每个文件和文件夹的作用、使用方法、注意事项等! 我再自动生成的项目中加了一下新的文件夹,分别存放不同类型的文件,让项目看起来更清晰&…...
2024/4/21 15:07:31 - 昆明哪家割双眼皮好
...
2024/4/21 15:07:30 - 银川华美整形做双眼皮一个星期图片
...
2024/4/21 15:07:29
最新文章
- 从虚拟化走向云原生,红帽OpenShift“一手托两家”
汽车行业已经迈入“软件定义汽车”的新时代。吉利汽车很清醒地意识到,只有通过云原生技术和数字化转型,才能巩固其作为中国领先汽车制造商的地位。 和很多传统企业一样,吉利汽车在走向云原生的过程中也经历了稳态业务与敏态业务并存带来的前所…...
2024/4/25 13:34:59 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 蓝桥杯第十五届抱佛脚(十)贪心算法
蓝桥杯第十五届抱佛脚(十)贪心算法 贪心算法基本概念 贪心算法是一种在算法设计中常用的方法,它在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。 贪…...
2024/4/19 0:49:59 - composer常见错误解决
在Java中,常见的问题和解决方法包括: 内存不足错误:Java应用程序在运行时可能会遇到内存不足的错误。可以通过增加JVM的堆内存大小来解决,可以通过设置-Xms和-Xmx参数来指定初始堆大小和最大堆大小。 java -Xms2G -Xmx4G YourAppl…...
2024/4/23 6:26:03 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/4/25 11:51:20 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/23 13:30:22 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/23 13:28:06 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/4/24 18:16:28 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/23 13:27:44 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/19 11:57:53 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/23 13:29:53 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/23 13:27:22 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/23 13:28:42 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/23 22:01:21 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/23 13:29:23 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/25 0:00:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/25 4:19:21 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/19 11:59:23 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/4/19 11:59:44 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/25 2:10:52 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/24 16:38:05 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/25 13:19:01 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/4/23 13:27:51 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/23 13:27:19 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57