'return await promise'와 'return promise'의 차이점
아래 코드 샘플을 감안할 때 동작에 차이가 있습니까? 그렇다면 그 차이점은 무엇입니까?
return await promise
async function delay1Second() {
return (await delay(1000));
}
return promise
async function delay1Second() {
return delay(1000);
}
내가 이해했듯이 첫 번째는 비동기 함수 내에서 오류 처리가 가능하며 오류는 비동기 함수의 Promise에서 버블 링됩니다. 그러나 두 번째는 틱이 하나 더 적게 필요합니다. 이 올바른지?
이 스 니펫은 참조를 위해 Promise를 반환하는 일반적인 함수입니다.
function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
대부분의 경우 return와 사이에는 눈에 띄는 차이가 없습니다 return await. 두 버전 모두 delay1Second똑같은 관찰 가능한 동작 을 가지고 있습니다 (그러나 구현에 따라 return await중간 Promise객체가 생성 될 수 있으므로 버전이 약간 더 많은 메모리를 사용할 수 있음).
그러나 @PitaJ가 지적했듯이 차이가있는 경우가 있습니다. returnor return await가 try- catch블록에 중첩 된 경우 입니다. 이 예를 고려하십시오
async function rejectionWithReturnAwait () {
try {
return await Promise.reject(new Error())
} catch (e) {
return 'Saved!'
}
}
async function rejectionWithReturn () {
try {
return Promise.reject(new Error())
} catch (e) {
return 'Saved!'
}
}
첫 번째 버전에서 비동기 함수는 결과를 반환하기 전에 거부 된 promise를 기다립니다. 이로 인해 거부가 예외로 바뀌고 catch절에 도달하게됩니다. 따라서이 함수는 "Saved!"문자열로 해결되는 promise를 반환합니다.
그러나 함수의 두 번째 버전은 비동기 함수 내에서 기다리지 않고 거부 된 약속을 직접 반환합니다. 즉, catch케이스가 호출 되지 않고 호출자가 대신 거부를받습니다.
다른 답변에서 언급했듯이, 약속을 직접 반환하여 버블 링 할 때 약간의 성능 이점이있을 수 있습니다. 그 이유는 결과를 먼저 기다린 다음 다른 약속으로 다시 래핑 할 필요가 없기 때문입니다. 그러나 아직 테일 콜 최적화에 대해 이야기 한 사람은 없습니다 .
테일 호출 최적화 또는 "적절한 테일 호출" 은 인터프리터가 호출 스택을 최적화하는 데 사용하는 기술입니다. 현재는 기술적으로 ES6 표준의 일부 임에도 불구 하고 아직 많은 런타임이 지원 하지는 않지만 향후 지원이 추가 될 수 있으므로 현재 좋은 코드를 작성하여 준비 할 수 있습니다.
간단히 말해서 TCO (또는 PTC) 는 다른 함수에서 직접 반환하는 함수에 대해 새 프레임을 열지 않음 으로써 호출 스택을 최적화합니다 . 대신 동일한 프레임을 재사용합니다.
async function delay1Second() {
return delay(1000);
}
에서 delay()직접 반환 되므로 delay1Second()PTC를 지원하는 런타임은 먼저 delay1Second()(외부 함수)에 대한 프레임을 열지 만 (내부 함수)에 대해 다른 프레임을 여는 대신 delay()외부 함수에 대해 열린 동일한 프레임을 재사용합니다. 이것은 매우 큰 재귀 함수 (예 :) 로 스택 오버플로 (hehe)를 방지 할 수 있기 때문에 스택을 최적화합니다 fibonacci(5e+25). 본질적으로 그것은 훨씬 더 빠른 루프가됩니다.
PTC is only enabled when the inner function is directly returned. It’s not used when the result of the function is altered before it is returned, for example, if you had return (delay(1000) || null), or return await delay(1000).
But like I said, most runtimes and browsers don’t support PTC yet, so it probably doesn’t make a huge difference now, but it couldn’t hurt to future-proof your code.
Read more in this question: Node.js: Are there optimizations for tail calls in async functions?
This is a hard question to answer, because it depends in practice on how your transpiler (probably babel) actually renders async/await. The things that are clear regardless:
Both implementations should behave the same, though the first implementation may have one less
Promisein the chain.Especially if you drop the unnecessary
await, the second version would not require any extra code from the transpiler, while the first one does.
So from a code performance and debugging perspective, the second version is preferable, though only very slightly so, while the first version has a slight legibility benefit, in that it clearly indicates that it returns a promise.
'Program Club' 카테고리의 다른 글
| scikit .predict () 기본 임계 값 (0) | 2020.12.04 |
|---|---|
| VS2013 Intellisense가 지속적으로 작동을 멈춤 (0) | 2020.12.04 |
| URL에서 뒤로 버튼 / 해시 변경 감지 (0) | 2020.12.04 |
| 소프트웨어 트랜잭션 메모리를 사용한 실제 경험이 있습니까? (0) | 2020.12.04 |
| null 포인터와 void 포인터의 차이점은 무엇입니까? (0) | 2020.12.03 |