이번 데브매칭에서 내가 하려고 했던 가장 이상한 짓은 클래스에 async await로 constructor를 만드는 것이였다.
저렇게 하면 리액트의 componeneDidMount를 구현할 수 있을 것이라고 생각했다. 하지만 그것은 불가능한 일이였고, 안타깝게도 스택오버플로우에는 나같은 짓을 하려는 사람이 적지 않았다.
Q. Is it bad practice to have a constructor function return a Promise?
답변: 맞다. constructor는 클래스의 인스턴스를 생성하고 초기화하는 일만 해야한다. constructor의 역할은 데이터 구조와 모든 인스턴스 프로퍼티를 세팅할 뿐, 다른 일을 수행하는 게 아니다. 가급적 사이드 이펙트가 없는 순수 함수여야 한다.
어떤 작업을 하고 싶으면 클래스의 메소드한테 시키면 된다. constructor가 data를 불러오게 하지말고, constructor의 parameter로 데이터를 넘겨야 한다. 불러오는 건 static 메소드한테 시키고, 그걸 체이닝하면 된다.
댓글: 가장 흔한 디자인 패턴은 constructor에 object shell 만들고, 모든 async 작업은 .init( ) 메소드에서 실행. 그렇게 하면 객체 안에 있는 인스턴스 데이터와 async 초기화 작업으로 생성된 객체 구조를 분리할 수 있다.
Q. 또 다른 질문
#1 절대 안된다는 사람
async await는 함수를 promise를 리턴하는 promise generator로 만든다.
constructor는 인스턴스를 초기화하고, 객체를 리턴한다.
promise 생기기 전에 쓰던 다른 디자인 패턴을 추천
var myObj = new myClass();
myObj.init(function() {
// inside here you can use myObj
});
class myClass {
constructor () {
}
init (callback) {
// do something async and call the callback:
// this가 콜백에서 myClass를 참조할 수 있음
callback.bind(this)();
}
}
+ static
: this가 가리키는 것은 클래스가 아니라 인스턴스 객체. static 함수는 인스턴스가 아니라 클래스에서만 쓸 수 있으니까 static 함수에서는 this 쓸 수 없다.
#2 된다는 사람
class AsyncConstructor {
constructor() {
return (async () => {
// All async code here
this.value = await asyncFunction();
return this; // when done
})();
}
}
let instance = await new AsyncConstructor();
- 아예 자기 호출 함수를 리턴하는 방식
- super 써야하면 또 안된다고 함
- 근데 이거 직접해보니 잘 안 됐던 것 같음
다른 질문에서도 async constructor() 는 syntax error라고 안된다고 한다.
대신 getter나 다른 메소드로는 가능. 다만 체이닝할 때 인스턴스의 state 관리를 잘 해줘야할 것.
stackoverflow.com/questions/43431550/async-await-class-constructor
'JS' 카테고리의 다른 글
[TIL] Promise, async/await (2) | 2022.06.12 |
---|---|
Node.js 공식 홈페이지 방문 (0) | 2021.05.11 |
배열 Array: 루프 (0) | 2021.03.08 |
중첩된 async await (0) | 2021.03.08 |
Fetch API (0) | 2021.03.05 |
댓글