업데이트 (2017)
2017 년에는 Promise가 JavaScript에 내장되어 ES2015 사양에 의해 추가되었습니다 (폴리 필은 IE8-IE11과 같은 오래된 환경에서 사용 가능). 그들이 사용했던 구문은 당신이 Promise
생성자 ( Promise
executor )에 전달하는 콜백을 사용합니다.이 콜백 은 인자로 프라 미스를 해결 / 거부하는 함수를받습니다.
첫째, async
이제 JavaScript에서 의미가 있기 때문에 (특정 컨텍스트에서는 키워드 일뿐 임에도 불구하고) later
혼란을 피하기 위해 함수의 이름으로 사용하겠습니다 .
기본 지연
네이티브 프라 미스 (또는 충실한 폴리 필)를 사용하면 다음과 같습니다.
function later(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
그 버전 가정합니다 setTimeout
그 준수의 브라우저에 대한 정의 곳 setTimeout
이 비 브라우저 환경에서 진실하지 않을 수 있습니다 (간격 후에을 제공하지 않는 콜백에 인수를 전달하지 않으며,로 사용하지 않았다 Firefox에서는 사실이지만 지금은 그렇습니다. Chrome에서는 사실이며 IE8에서도 마찬가지입니다.)
가치가있는 기본 지연
함수가 선택적으로 해상도 값을 전달하도록 setTimeout
하려면 지연 후 추가 인수를 제공 한 다음 호출시 콜백에 전달할 수있는 모호한 최신 브라우저에서이를 수행 할 수 있습니다 (현재 Firefox 및 Chrome, IE11 + , 아마도 Edge; IE8 또는 IE9가 아니라 IE10에 대한 정보 없음) :
function later(delay, value) {
return new Promise(function(resolve) {
setTimeout(resolve, delay, value);
});
}
ES2015 + 화살표 기능을 사용하는 경우 더 간결 할 수 있습니다.
function later(delay, value) {
return new Promise(resolve => setTimeout(resolve, delay, value));
}
또는
const later = (delay, value) =>
new Promise(resolve => setTimeout(resolve, delay, value));
값이있는 취소 가능한 지연
시간 제한을 취소 할 수 있도록하려면 약속을 later
취소 할 수 없기 때문에 에서 약속을 반환 할 수 없습니다.
그러나 우리는 프라 미스에 대한 cancel
메소드와 접근자를 가진 객체를 쉽게 반환 할 수 있으며 취소시 프라 미스를 거부 할 수 있습니다.
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
라이브 예 :
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
const l1 = later(100, "l1");
l1.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l1 cancelled"); });
const l2 = later(200, "l2");
l2.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l2 cancelled"); });
setTimeout(() => {
l2.cancel();
}, 150);
2014 년의 원래 답변
일반적으로 약속 라이브러리가 있습니다 (하나는 직접 작성하거나 여러 개 중 하나). 해당 라이브러리에는 일반적으로 생성하고 나중에 "해결"할 수있는 객체가 있으며, 해당 객체에는 얻을 수있는 "약속"이 있습니다.
그러면 다음 later
과 같은 경향이 있습니다.
function later() {
var p = new PromiseThingy();
setTimeout(function() {
p.resolve();
}, 2000);
return p.promise();
}
질문에 대한 의견에서 다음과 같이 질문했습니다.
자신 만의 약속 라이브러리를 만들려고합니까?
그리고 당신은 말했다
나는 아니었지만 이제는 그것이 실제로 내가 이해하려고 노력한 것 같습니다. 도서관이하는 방법
이러한 이해를 돕기 위해 원격으로 Promises-A를 준수하지 않는 매우 기본적인 예가 있습니다. Live Copy
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Very basic promises</title>
</head>
<body>
<script>
(function() {
var PromiseThingy = (function() {
function triggerCallback(callback, promise) {
try {
callback(promise.resolvedValue);
}
catch (e) {
}
}
function Promise() {
this.callbacks = [];
}
Promise.prototype.then = function(callback) {
var thispromise = this;
if (!this.resolved) {
this.callbacks.push(callback);
}
else {
setTimeout(function() {
triggerCallback(callback, thispromise);
}, 0);
}
return this;
};
function PromiseThingy() {
this.p = new Promise();
}
PromiseThingy.prototype.resolve = function(value) {
var n;
if (!this.p.resolved) {
this.p.resolved = true;
this.p.resolvedValue = value;
for (n = 0; n < this.p.callbacks.length; ++n) {
triggerCallback(this.p.callbacks[n], this.p);
}
}
};
PromiseThingy.prototype.promise = function() {
return this.p;
};
return PromiseThingy;
})();
function later() {
var p = new PromiseThingy();
setTimeout(function() {
p.resolve();
}, 2000);
return p.promise();
}
display("Start " + Date.now());
later().then(function() {
display("Done1 " + Date.now());
}).then(function() {
display("Done2 " + Date.now());
});
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
</script>
</body>
</html>