injectArgs这是angular种依赖注入代码摘录,看了半天,始终没有头绪,脑袋不够用了!感觉整个人都不好了!
export const enum InjectFlags {
Default = 0 << 0, // 0b0000
Host = 1 << 0, // 0b0001
Self = 1 << 1, // 0b0010
SkipSelf = 1 << 2, // 0b0100
Optional = 1 << 3, // 0b1000
}
| 或 | Default0b0000 |
Host0b0001 |
Self0b0010 |
SkipSelf0b0100 |
Optional0b1000 |
|---|---|---|---|---|---|
Default0b0000 |
0b0000 |
0b0001 |
0b0010 |
0b0100 |
0b1000 |
Host0b0001 |
0b0001 |
0b0001 |
0b0011 |
0b0101 |
0b1001 |
Self0b0010 |
0b0010 |
0b0011 |
0b0010 |
0b0110 |
0b1010 |
SkipSelf0b0100 |
0b0100 |
0b0101 |
0b0110 |
0b0100 |
0b1100 |
Optional0b1000 |
0b1000 |
0b1001 |
0b1010 |
0b1100 |
0b1000 |
@Default() 0b0000 * @Host() 0b0001 * @Self() 0b0010 * @SkipSelf() 0b0100 * @Optional() 0b1000 = 0b1111 4个二进制第一位标示Host是否开启,二位表示Self是否开启,三位表示SkipSelf是否开启,4位表示Optional是否开启。
// 这样的代码跟天数有啥区别
export function injectArgs(
types: (Type<any> | InjectionToken<any> | any[])[]
): any[] {
const args: any[] = [];
for (let i = 0; i < types.length; i++) {
const arg = types[i];
if (Array.isArray(arg)) {
if (arg.length === 0) {
throw new Error('Arguments array must have arguments.');
}
let type: Type<any> | undefined = undefined;
let flags: InjectFlags = InjectFlags.Default;
for (let j = 0; j < arg.length; j++) {
const meta = arg[j];
if (meta instanceof Optional || meta.ngMetadataName === 'Optional') {
flags |= InjectFlags.Optional;
} else if (meta instanceof SkipSelf || meta.ngMetadataName === 'SkipSelf') {
flags |= InjectFlags.SkipSelf;
} else if (meta instanceof Self || meta.ngMetadataName === 'Self') {
flags |= InjectFlags.Self;
} else if (meta instanceof Inject) {
type = meta.token;
} else {
type = meta;
}
}
args.push(inject(type!, flags));
} else {
args.push(inject(arg));
}
}
return args;
}
export const enum OptionFlags {
Optional = 1 << 0, // 0b0001
CheckSelf = 1 << 1, // 0b0010
CheckParent = 1 << 2, // 0b0100
Default = CheckSelf | CheckParent // 0b0110
}
| 与 | Optional0b0001 |
CheckSelf0b0010 |
CheckParent0b0100 |
Default0b0110 |
|---|---|---|---|---|
Optional0b0001 |
0b0001 |
0b0000 |
0b0000 |
0b0000 |
CheckSelf0b0010 |
0b0000 |
0b0010 |
0b0000 |
0b0010 |
CheckParent0b0100 |
0b0000 |
0b0000 |
0b0100 |
0b0100 |
Default0b0110 |
0b0000 |
0b0010 |
0b0100 |
0b0110 |
@Optional & @Optional 不为0,其余均为0
@CheckSelf & @CheckSelf 和 @CheckSelf & @Default 不为0,其余均为0
@CheckParent & @CheckParent 和 @CheckParent & @Default 不为0,其余均为0
@Default & @Optional 为0,其余不为0
InjectFlags各个值&的话,只有自身与自身结果为正,其余均为0.
// 根据token解析出value
function resolveToken(
token: any,
record: Record | undefined,
records: Map<any, Record>,
parent: Injector,
notFoundValue: any,
flags: InjectFlags
): any {
let value;
// 没有SkipSelf
if (record && !(flags & InjectFlags.SkipSelf)) {
value = record.value;
// circular
if (value == CIRCULAR) {
throw Error(NO_NEW_LINE + 'Circular dependency');
} else if (value === EMPTY) { // empty
record.value = CIRCULAR;
let obj = undefined;
let useNew = record.useNew;
let fn = record.fn;
let depRecords = record.deps;
let deps = EMPTY;
if (depRecords.length) {
deps = [];
for (let i = 0; i < depRecords.length; i++) {
const depRecord: DependencyRecord = depRecords[i];
const options = depRecord.options;
const childRecord =
// 如果是options = Default|CheckSelf
options & OptionFlags.CheckSelf ?
records.get(depRecord.token) : undefined;
deps.push(
// 递归
tryResolveToken(
depRecord.token,
childRecord,
records,
// childRecord && options != Default|CheckParent
!childRecord && !(options & OptionFlags.CheckParent) ? NULL_INJECTOR : parent,
// options == Default|Optional
options & OptionFlags.Optional ? null : Injector.THROW_IF_NOT_FOUND,
InjectFlags.Default
)
);
}
}
record.value = value = useNew ? new (fn as any)(...deps) : fn.apply(obj, deps);
}
} else if (!(flags & InjectFlags.Self)) {
// 获取上级
value = parent.get(
token,
notFoundValue,
InjectFlags.Default
);
}
return value;
}
// 计算deps
function computeDeps(provider: StaticProvider): DependencyRecord[] {
let deps: DependencyRecord[] = EMPTY;
const providerDeps: any[] =
(provider as ExistingProvider & StaticClassProvider & ConstructorProvider).deps;
if (providerDeps && providerDeps.length) {
deps = [];
for (let i = 0; i < providerDeps.length; i++) {
let options = OptionFlags.Default;
let token = resolveForwardRef(providerDeps[i]);
if (token instanceof Array) {
for (let j = 0, annotations = token; j < annotations.length; j++) {
const annotation = annotations[j];
if (annotation instanceof Optional || annotation == Optional) {
options = options | OptionFlags.Optional;
} else if (annotation instanceof SkipSelf || annotation == SkipSelf) {
// 按位取反运算符 (~)
options = options & ~OptionFlags.CheckSelf;
} else if (annotation instanceof Self || annotation == Self) {
// 按位取反运算符 (~)
options = options & ~OptionFlags.CheckParent;
} else if (annotation instanceof Inject) {
token = (annotation as Inject).token;
} else {
token = resolveForwardRef(annotation);
}
}
}
deps.push({ token, options });
}
} else if ((provider as ExistingProvider).useExisting) {
const token = resolveForwardRef((provider as ExistingProvider).useExisting);
deps = [{ token, options: OptionFlags.Default }];
} else if (!providerDeps && !(USE_VALUE in provider)) {
throw staticError('\'deps\' required', provider);
}
return deps;
}
我给你跪了!都是什么鬼!