약속은 단지 구문 설탕이라고 말하는 것이 공정합니다. 콜백으로 할 수있는 약속으로 할 수있는 모든 것. 실제로, 대부분의 promise 구현은 원할 때마다 둘 사이를 변환하는 방법을 제공합니다.
약속이 더 나은 이유는 약속이 더 작기 때문입니다 . 이는 여러 약속을 결합하는 것이 "단순히 작동하지만"여러 콜백을 결합하는 것은 종종 그렇지 않음을 의미합니다. 예를 들어, 약속을 변수에 할당하고 나중에 추가 핸들러를 추가하거나 모든 약속이 해결 된 후에 만 실행되는 대규모 약속 그룹에 핸들러를 첨부하는 것은 사소한 일입니다. 당신은 일종의 콜백으로 이러한 것들을 모방 할 수 있지만, 그것은 더 많은 코드를 걸립니다 아주 제대로 수행하기 어려운, 그리고 최종 결과는 일반적으로 훨씬 적은 유지 보수입니다.
조합 가능성을 보장하는 가장 크고 (미묘한) 방법 중 하나는 반환 값과 잡히지 않은 예외를 균일하게 처리하는 것입니다. 콜백을 사용하면 예외를 처리하는 방법은 중첩 된 많은 콜백 중 어느 것이 콜백을 수행했는지와 콜백을 수행하는 함수 중 구현에 try / catch가있는 기능에 전적으로 달려 있습니다. 약속, 당신은 알고 하나 개의 콜백 함수를 탈출 예외가 잡힌하고 함께 제공되는 오류 처리기에 전달됩니다 .error()
나 .catch()
.
단일 콜백 대 단일 약속에 대한 예에서 중요한 차이점은 없습니다. 그것은 당신이 약속 기반 코드가 훨씬 더 좋아 보이는 경향을 가진 대폭 선 약속 대 단거리 콜백이있을 때입니다.
다음은 약속으로 작성된 가상 코드에 대한 시도와 콜백을 사용하여 내가 말하는 것에 대한 아이디어를 줄 정도로 복잡해야합니다.
약속과 함께 :
createViewFilePage(fileDescriptor) {
getCurrentUser().then(function(user) {
return isUserAuthorizedFor(user.id, VIEW_RESOURCE, fileDescriptor.id);
}).then(function(isAuthorized) {
if(!isAuthorized) {
throw new Error('User not authorized to view this resource.'); // gets handled by the catch() at the end
}
return Promise.all([
loadUserFile(fileDescriptor.id),
getFileDownloadCount(fileDescriptor.id),
getCommentsOnFile(fileDescriptor.id),
]);
}).then(function(fileData) {
var fileContents = fileData[0];
var fileDownloads = fileData[1];
var fileComments = fileData[2];
fileTextAreaWidget.text = fileContents.toString();
commentsTextAreaWidget.text = fileComments.map(function(c) { return c.toString(); }).join('\n');
downloadCounter.value = fileDownloads;
if(fileDownloads > 100 || fileComments.length > 10) {
hotnessIndicator.visible = true;
}
}).catch(showAndLogErrorMessage);
}
콜백 사용 :
createViewFilePage(fileDescriptor) {
setupWidgets(fileContents, fileDownloads, fileComments) {
fileTextAreaWidget.text = fileContents.toString();
commentsTextAreaWidget.text = fileComments.map(function(c) { return c.toString(); }).join('\n');
downloadCounter.value = fileDownloads;
if(fileDownloads > 100 || fileComments.length > 10) {
hotnessIndicator.visible = true;
}
}
getCurrentUser(function(error, user) {
if(error) { showAndLogErrorMessage(error); return; }
isUserAuthorizedFor(user.id, VIEW_RESOURCE, fileDescriptor.id, function(error, isAuthorized) {
if(error) { showAndLogErrorMessage(error); return; }
if(!isAuthorized) {
throw new Error('User not authorized to view this resource.'); // gets silently ignored, maybe?
}
var fileContents, fileDownloads, fileComments;
loadUserFile(fileDescriptor.id, function(error, result) {
if(error) { showAndLogErrorMessage(error); return; }
fileContents = result;
if(!!fileContents && !!fileDownloads && !!fileComments) {
setupWidgets(fileContents, fileDownloads, fileComments);
}
});
getFileDownloadCount(fileDescriptor.id, function(error, result) {
if(error) { showAndLogErrorMessage(error); return; }
fileDownloads = result;
if(!!fileContents && !!fileDownloads && !!fileComments) {
setupWidgets(fileContents, fileDownloads, fileComments);
}
});
getCommentsOnFile(fileDescriptor.id, function(error, result) {
if(error) { showAndLogErrorMessage(error); return; }
fileComments = result;
if(!!fileContents && !!fileDownloads && !!fileComments) {
setupWidgets(fileContents, fileDownloads, fileComments);
}
});
});
});
}
약속없이 콜백 버전에서 코드 중복을 줄이는 영리한 방법이있을 수 있지만, 내가 생각할 수있는 모든 것은 약속 같은 것을 구현하는 것으로 요약 할 수 있습니다.