- Published on
no return, await, return, await return 의 차이
- Author
- Name
- yceffort
50% 확률로 reject 되는 아래와 같은 함수가 있다고 가정해보자.
async function resolveOrReject() {
// 1초를 그냥 기다린다.
await new Promise((_) => setTimeout(_, 1000))
// 50% 확률로 true false
const randomResult = Boolean(Math.round(Math.random()))
if (randomResult) {
return 'good'
} else {
throw Error('bad')
}
}
그냥 호출
async function a() {
try {
resolveOrReject()
} catch (e) {
return 'caught!'
}
}
이 경우 a()
는 1초를 기다리지 않고 언제나 undefined
를 fulfilled
(이행) 할 것이다. 우리가 여기에서 await
하거나 껼과를 기다리지 않으므로, 실패했을 경우에 대해서 처리를 할 수가 없다. 대부분 이런 코드는 실수일것이다.
await
async function b() {
try {
await resolveOrReject()
} catch (e) {
return 'caught!'
}
}
이 함수의 경우에는 항상 1초를 기다리며, undefined
가 오거나 caught
가 올 것이다. resolveOrReject
의 결과를 기다리기 때문에, 실패 했을 경우 catch
블록을 실행할 수 있게 되었다. 그러나 실패하지 않았을 경우에는 이 값을 가지고 아무것도 하지 않는다.
return
async function c() {
try {
return resolveOrReject()
} catch (e) {
return 'caught'
}
}
이 경우에도 마찬가지로 1초를 기다리며, 성공할 경우 good
이 오고, 실패할 경우에는 caught
가 오는 것이 아니고 그냥 에러가 던져진다. 따라서 실패할 경우엔 catch
블록에 들어가지 않는다는 것을 알 수 있다.
return await
async function d() {
try {
return await resolveOrReject()
} catch (e) {
return 'caught'
}
}
1초를 기다리며, good
이 오거나 caught
가 오게 된다. resolveOrReject
의 결과를 기다리므로, 에러가 났을 때는 catch
블록으로 , 이행이 되었을 경우 정상적으로 결과를 리턴한다.
위 함수를 나누면 이렇게 볼 수 있다.
async function d() {
try {
// resolveOrReject 의 결과를 기다리며, 결과를 변수에 넣는다.
const result = await resolveOrReject()
// 만약 위에서 에러가 던져졌다면, catch 블록으로 넘어간다.
// 그렇지 않으면, 결과를 리턴한다.
return result
} catch (e) {
return 'caught'
}
}
이 것은 어디까지나 try ... catch
블록에서만 유효하다. 그 외의 영역에서는 return await
은 의미하다. async
함수 내에 있는 return await
은 프로미스를 기다렸다가 결과가 나올때까지, 현재의 함수를 콜스택에 넣어두며, 외부 promise가 resolve 되기전에 추가로 마이크로 태스크가 생기게 된다. 따라서 try ... catch
블록이 아니라면 단순히 return something
으로 처리하면 된다.
https://github.com/eslint/eslint/blob/master/docs/rules/no-return-await.md