Js
异步与构造函数
为什么不在 constructor 中使用异步?https://stackoverflow.com/questions/43431550/async-await-class-constructor#answer-52431905
为什么不在 React 的组件构造函数中获取数据?https://stackoverflow.com/a/38913497/14602831
首先,构造函数不可以是一个 async 函数:
也就是 构造函数只能返回一个纯对象
其次,构造函数中是可以 异步设置 this 的,但似乎没什么意义:
React 其实也可以在构造函数中获取数据,但依旧需要 setState 才能生效,异步后修改 this.state 是无法触发渲染的。
而之前之所以约定俗成的说一定要在 didMount 中调用是因为,早期 React 存在 bug,非didMount 中的 setState 有一定几率不响应。
那如果一定要用 async 来构造一个东西
创建一个 builder:
实例只可从 build 函数中创建,此时相当于在 new 操作前植入一段异步处理
class myClass {constructor (async_param) {if (typeof async_param === 'undefined') {throw new Error('Cannot be called directly');}}static async build () {var async_result = await doSomeAsyncStuff();return new myClass(async_result);}}
从这里也能看出来整个流程是静态的。即使使用 builder ,此时的创建流程也依旧是无法干涉 实例的。
还有一种臊皮的操作:
通过匿名函数立即执行(IEFES)
class AsyncConstructor {constructor() {return (async () => {// All async code herethis.value = await asyncFunction();return this; // when done})();}}let instance = await new AsyncConstructor();
当然此处 super 无法在 async 中执行,Ts也因为各种问题无法通过。但可以用
https://gist.github.com/vipulwairagade/a77bdd85909d61e3f7d87f2dcc57f2b1
Typescript
元组拓展/可拓展泛型参数
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html
利用参数类型为元组,函数提供泛型接口,即可实现参数的可拓展:
type Arr = readonly unknown[];function partialCall<T extends Arr, U extends Arr, R>(f: (...args: [...T, ...U]) => R,...headArgs: T) {return (...tailArgs: U) => f(...headArgs, ...tailArgs);}
所以 React 的 props 类型也同理:
type Origin = [number]interface Props<T extends any[]> {fn: (...args: [...Origin, ...T]) => void}
使用时推导如下:
