일.인터페이스 분석
###1.핵심 기능
- resolve(value)/reject(err)
생성자 파라미터 resolve/reject 는 정적 메서드도 인스턴스 메서드도 아니지만, 데이터 진입점이므로 promise API 의 핵심입니다. promise 메커니즘의 대부분 비밀은 여기에 있으며, 모든 공개 인터페이스는 이를 기반으로 작동합니다
- then(onFulfilled, onRejected)
resolve/reject 외에, then 은 절대적으로 가장 중요합니다. 다른 모든 인스턴스 메서드/정적 메서드는 필수가 아니지만, then 은 필수불가결합니다. 다시 말해, new Promise 할 수 있고 then 도 지원하면, 전체 promise 메커니즘이 완성되며, 다른 인터페이스는 모두 금상첨화인 것으로, promise 를 더 사용하기 쉽게 할 뿐입니다
###2.인스턴스 메서드
- catch(onRejected)
promise.then(null, onRejected) 와 동등하며, 사용자는 조금 적은 코드를 작성할 수 있고, 동시에 의미를 부여합니다 (catch error)
###3.정적 메서드
- Promise.resolve(value)
wrapper 를 제공하며, value 가 Promise 인스턴스인지 아닌지 확실하지 않을 때, 이 메서드를 사용하여 포장된 Promise 인스턴스를 얻을 수 있습니다. 내부 메커니즘은 비교적 복잡하며, 상세 정보는 [6.Promise.resolve(value) 해결](/articles/完全理解 promise/#articleHeader14) 참조
- Promise.reject(reason)
同様に wrapper 를 제공하며, 부정 Promise 를 생성하는 쇼트컷 방식입니다. 내부 메커니즘은 Promise.resolve(value) 보다 훨씬 간단합니다
- Promise.all(iterable)
모두 정상적으로 완료되거나, 또는 오류로 중단되며, 미완료된 것은 모두 정지
- Promise.race(iterable)
「경쟁」, 결과가 긍정인지 부정인지와 관계없이, 가장 빠른 것만
###4.고급 기능
-
결과 자동 후투
// 错误后抛 new Promise(function(resolve, reject) {reject('x')}) .then(null) .then(null) .catch(function(err) {console.log(err)}) // 值后抛 new Promise(function(resolve, reject) {resolve('x')}) .catch(null) .catch(null) .then(function(future) {console.log(future)})
오류는 마지막 catch 에 던져지며, 「먹히지」않으면 자동으로 후투되며, 마지막에 「먹히거나」, 최상층에 던져져 오류 보고
-
결과 자동 외투
// 外层 then 能够拿到内层 future 和 error new Promise(function(resolve, reject) { resolve(new Promise(function(resolve, reject) { resolve(12); // reject(new Error('reject in nested Promise')); }).then(function(future) { return future + 1; }, function(error) { return new Error('reject again in nested Promise'); })); }).then(onFulfilled, onRejected);
외층의 then 은 내층의 future 와 error 를 얻을 수 있어, 수동으로 상태를 유지할 필요를 피하고, 오류 집중 처리에도 유리
이.난점
난점은 promise 메커니즘 자체가비동기라는 것입니다. 예는 다음과 같습니다:
var p = new Promise(function(resolve, reject) {resolve(1)}).then(function(future) {return 2;});
// 立即输出 p
console.log(p);
// 1s 后输出 p
setTimeout(function() {
console.log(p);
}, 1000);
즉시 출력 결과는:
// console
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1 초 후 출력 결과는:
// console
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
이러한 비동기 메커니즘 하에서, return 과 throw 는 모두 문제가 됩니다. 예를 들어:
// 异步
function nextTick(fn) {
setTimeout(fn, 0);
}
// test
try {
nextTick(function() {
throw new Error('x');
});
}
catch (err) {
console.log('err: ' + err.message);
}
결과는 오류를 catch 할 수 없으며, x 는 최상층에 던져져 콘솔에 표시됩니다. try..catch 를 넣는 것을 쉽게 생각할 수 있습니다. 네, 오류는 확실히 catch 되었지만, 어떻게 외층에 통지할까요?
return 과 throw 는 모두 값 전달 수단으로, 비동기 환경에서는 직접 사용할 수 없어, 스스로 하나의 값 전달 메커니즘을 구현해야 합니다. 이것이 난점입니다
P.S. 어떤 기사에서 try...catch 의 단점에 대해 언급했습니다. 상세 정보는 前端코드 이상 모니터링 참조
삼.프로젝트 주소
주소:ayqy / myPromise - 코드 호스팅 - 오픈소스 중국 커뮤니티
주의:현재 버전 (v0.1.0 2015/12/13) 에는 큰 문제가 있으며, 절대로 직접 사용하지 마십시오. 현재 내부 메커니즘은 동기이기 때문입니다
P.S. 버전이 사용 가능하게 업데이트될 때, 필자는 여기서 설명합니다. 그之前에는, 더 신뢰할 수 있는 taylorhakes/promise-polyfill · GitHub 을 사용할 것을 권장합니다. 매우 경량인 구현입니다
참고 자료
- [번역] We have a problem with promises:promise 의 실행 메커니즘을 이해하면 이러한 문제는 발생하지 않습니다. 4 종류의 promise 의 차이에 대해서도 말할 것은 없지만,文中에서 언급된 오류는 주의할 가치가 있습니다
아직 댓글이 없습니다