Promise의 구현 원리
5439 단어 Promise 관련
var Deferred = function () {
this.promise = new Promise();
};
var Promise = function () {
this.queue = [];
this.isPromise = true; // promise
}
Promise.prototype.then = function (fulfilledHandler,errorHandler,progressHandler) {
var handler = {};
if(typeof fulfilledHandler === 'function'){
handler.fulfilled = fulfilledHandler;
}
if(typeof errorHandler === 'function'){
handler.error = errorHandler;
}
this.queue.push(handler);
return this;
}
//
Deferred.prototype.callback = function () {
var that = this;
return function (err,file) {
if(err){
return that.reject(err);
}
that.resolve(file);
}
}
Deferred.prototype.resolve = function (obj) {
var promise = this.promise;
var handler;
while(handler = promise.queue.shift()){
if(handler && handler.fulfilled){
var ret = handler.fulfilled(obj);
if(ret &&ret.isPromise){
ret.queue = promise.queue;
this.promise = ret;
return ret;
}
}
}
}
Deferred.prototype.reject = function (err) {
var promise = this.promise,handler;
while(handler = promise.queue.shift()){
if(handler && handler.error){
var ret = handler.error(err);
if(ret && ret.isPromise){
ret.queue = promise.queue;
this.promise = ret;
return ;
}
}
}
}
여기에서 우리는 이 설계의 타당성을 검증하기 위해 두 번의 파일 읽기를 예로 들었다.여기서 두 번째 파일을 읽는 것은 첫 번째 파일의 내용에 의존한다고 가정하고 관련 코드는 다음과 같다.
var readFile1 = function (file,encoding) {
var deferred = new Deferred();
fs.readFile(file,encoding,deferred.callback());
return deferred.promise;
}
var readFile2 = function (file,encoding) {
var deferred = new Deferred();
fs.readFile(file,encoding,deferred.callback());
return deferred.promise;
}
readFile1('file1.txt','utf8').then(function (file1) {
return readFile2(file1.trim(),'utf8');
}).then(function (file2) {
console.log(file2);
});
Promise가 체인식 실행을 지원하려면 다음과 같은 두 가지 절차를 통해 (1) 모든 리셋을 대기열에 저장(2) Promise가 완성되면 하나하나 리셋을 실행합니다. 새로운 Promise 대상이 검출되면 실행을 중지하고 현재 deferred 대상의 Promise 인용을 새로운 Promise 대상으로 바꾸고 대기열의 나머지 리셋을 전달합니다.
이곳의 코드는 주로 Promise의 집행 원리를 연구하는 데 사용되며 더 많은 세부 사항의 최적화에 있어 Q나 when 등 Promise 라이브러리가 더욱 잘 되어 실제 응용할 때 이러한 성숙한 라이브러리를 사용하십시오.
주의:
Promise.prototype.then
의 함수 구현 중return this;
에서만 체인 호출이 이루어졌고,this는 현재promise의 실례를 가리킨다.