angular裡forwardRef的原理
阿新 • • 發佈:2020-12-10
一段會報錯的angular程式碼
@Injectable() class Socket { constructor(private buffer: Buffer) { } } console.log(Buffer); // undefined @Injectable() class Buffer { constructor(@Inject(BUFFER_SIZE) private size: Number) { } } console.log(Buffer); // [Function: Buffer]
翻譯一下
var providerList = new Map(); function Injectable(cls, deps) { providerList.set(cls, { deps: deps, instance: null }); } function inject(cls) { var instanceObj = providerList.get(cls); if (instanceObj === undefined) { return null; } else if (instanceObj.instance === null) { var deps = instanceObj.deps.map(dep => inject(dep)); var instance = cls.apply({}, deps); instanceObj.instance = instance; return instance; } else { return instanceObj.instance; } } var Socket = (function() { function Socket(buffer) { this.buffer = buffer; return this; } Injectable(Socket, [Buffer]); return Socket; }()); var Buffer = (function () { function Buffer() { this.sayHello = function() { console.log('hello, i am Buffer.'); } return this; } Injectable(Buffer, []); return Buffer; }()); var socket = inject(Socket); socket.buffer.sayHello();
Socket被注入的時候,他的依賴Buffer還是undefined狀態,最後取出來的就是undefined.
看看angular怎麼用forwardRef解決這個問題的
@Injectable() class Socket { constructor(@Inject(forwardRef(() => Buffer) private buffer) { } } @Injectable() class Buffer { constructor() { } }
翻譯一下
function forwardRef(forwardRefFn) { forwardRefFn.__forward_ref__= forwardRef; return forwardRefFn; } function resolveForwardRef(type) { if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') && type.__forward_ref__ === forwardRef) { return type(); } else { return type; } }var providerList = new Map(); function Injectable(cls, deps) { providerList.set(cls, { deps: deps, instance: null }); } function inject(cls) { cls = resolveForwardRef(cls); var instanceObj = providerList.get(cls); if (instanceObj === undefined) { return null; } else if (instanceObj.instance === null) { var deps = instanceObj.deps.map(dep => inject(dep)); var instance = cls.apply({}, deps); instanceObj.instance = instance; return instance; } else { return instanceObj.instance; } } var Socket = (function() { function Socket(buffer) { this.buffer = buffer; return this; } Injectable(Socket, [forwardRef(() => Buffer)]); return Socket; }()); var Buffer = (function () { function Buffer() { this.sayHello = function() { console.log('hello, i am Buffer.'); } return this; } Injectable(Buffer, []); return Buffer; }()); var socket = inject(Socket); socket.buffer.sayHello();
原理就是依賴不再是類了,而是一個返回類的函式,這樣在inject的時候避免注入undefined。