약속에는 상태가 있으며 보류 중으로 시작하여 다음과 같이 해결할 수 있습니다.
- 계산이 성공적으로 완료 되었음을 의미합니다.
- 거부 계산이 실패했음을 의미한다.
약속 반환 함수 는 절대 던져서 는 안되며 거부를 반환해야합니다. 약속 반환 함수에서 던지면 a } catch {
와 a를 모두 사용해야합니다 .catch
. 약속 된 API를 사용하는 사람들은 약속을 던질 것으로 기대하지 않습니다. JS에서 비동기 API가 어떻게 작동하는지 잘 모르겠다면 먼저이 답변을 참조하십시오 .
1. DOM로드 또는 다른 일회성 이벤트 :
따라서 약속을 만드는 것은 일반적으로 약속 시간을 지정하는 것을 의미합니다. 즉, 데이터가 사용 가능하고로 액세스 할 수 있음을 나타 내기 위해 이행 또는 거부 단계로 이동할 때를 의미합니다 .then
.
Promise
기본 ES6 약속과 같은 생성자 를 지원하는 최신 약속 구현을 통해 :
function load() {
return new Promise(function(resolve, reject) {
window.onload = resolve;
});
}
그런 다음 결과 약속을 다음과 같이 사용하십시오.
load().then(function() {
// Do things after onload
});
지연을 지원하는 라이브러리를 사용하는 경우 (이 예제에서는 $ q를 사용하지만 나중에 jQuery도 사용합니다) :
function load() {
var d = $q.defer();
window.onload = function() { d.resolve(); };
return d.promise;
}
또는 API와 같은 jQuery를 사용하여 한 번 발생하는 이벤트에 연결하십시오.
function done() {
var d = $.Deferred();
$("#myObject").once("click",function() {
d.resolve();
});
return d.promise();
}
2. 일반 콜백 :
이 API는 꽤 일반적이기 때문에… 콜백은 JS에서 일반적입니다. 가지고있는 일반적인 경우에서 살펴 보자 onSuccess
과 onFail
:
function getUserData(userId, onLoad, onFail) { …
Promise
기본 ES6 약속과 같은 생성자 를 지원하는 최신 약속 구현을 통해 :
function getUserDataAsync(userId) {
return new Promise(function(resolve, reject) {
getUserData(userId, resolve, reject);
});
}
지연을 지원하는 라이브러리를 사용하는 경우 (이 예제에서는 jQuery를 사용하지만 위의 $ q도 사용했습니다) :
function getUserDataAsync(userId) {
var d = $.Deferred();
getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });
return d.promise();
}
jQuery는 또한 다음 과 같이 양식을 $.Deferred(fn)
매우 에뮬레이트하는 표현식을 작성할 수있는 장점이있는 new Promise(fn)
양식을 제공합니다.
function getUserDataAsync(userId) {
return $.Deferred(function(dfrd) {
getUserData(userId, dfrd.resolve, dfrd.reject);
}).promise();
}
참고 : 여기서는 jQuery 지연 resolve
및 reject
메소드가 "분리 가능" 하다는 사실을 이용합니다 . 즉. 그것들은 jQuery.Deferred () 의 인스턴스 에 바인딩됩니다 . 모든 라이브러리가이 기능을 제공하는 것은 아닙니다.
3. 노드 스타일 콜백 ( "nodeback") :
노드 스타일 콜백 (노드 백)은 콜백이 항상 마지막 인수이고 첫 번째 매개 변수가 오류 인 특정 형식을 갖습니다. 먼저 하나를 수동으로 약속합시다.
getStuff("dataParam", function(err, data) { …
에:
function getStuffAsync(param) {
return new Promise(function(resolve, reject) {
getStuff(param, function(err, data) {
if (err !== null) reject(err);
else resolve(data);
});
});
}
지연을 사용하면 다음을 수행 할 수 있습니다 (이 예제에서는 Q를 사용하지만 Q 는 선호 하는 새로운 구문 을 지원하지만 ).
function getStuffAsync(param) {
var d = Q.defer();
getStuff(param, function(err, data) {
if (err !== null) d.reject(err);
else d.resolve(data);
});
return d.promise;
}
일반적으로 노드를 염두에두고 설계된 대부분의 약속 라이브러리와 노드 8+의 기본 약속에는 노드 백을 약속하는 방법이 내장되어 있습니다. 예를 들어
var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // Native promises, node only
4. 노드 스타일 콜백이있는 전체 라이브러리 :
여기에는 황금률이 없으며 하나씩 약속합니다. 그러나 일부 약속 구현을 사용하면 예를 들어 Bluebird에서 노드 백 API를 약속 API로 변환하는 것이 다음과 같이 간단합니다.
Promise.promisifyAll(API);
또는 Node의 기본 약속 으로 :
const { promisify } = require('util');
const promiseAPI = Object.entries(API).map(([key, v]) => ({key, fn: promisify(v)}))
.reduce((o, p) => Object.assign(o, {[p.key]: p.fn}), {});
노트:
- 물론, 당신이
.then
핸들러 에있을 때 당신은 일을 약속 할 필요가 없습니다. .then
처리기 에서 약속을 반환하면 해당 약속의 값으로 해결되거나 거부됩니다. .then
처리기 에서 던지는 것도 좋은 습관이며 약속을 거부합니다. 이것은 유명한 약속 던지기 안전입니다.
- 실제로
onload
는을 사용 addEventListener
하지 않아야합니다 onX
.