我對JavaScript進行了相當的代碼編寫,雖然我認爲我確實瞭解承諾的工作原理,但我不確定是否完全理解承諾爲JS世界帶來的優勢。考慮下面的代碼,簡單地說帶有包含更多調用的回調的異步調用等等。瞭解JavaScript中的承諾
(function doWorkOldSchool() {
setTimeout(function() {
// once done resolve promise
console.log("work done");
setTimeout(function goHome() {
// once done resolve promise
console.log("got home");
try {
setTimeout(function cookDinner() {
// this exception will not be caught
throw "No ingredients for dinner!";
console.log("dinner cooked");
setTimeout(function goToSleep() {
// once done resolve promise
console.log("go to sleep");
}, 2000);
}, 2000);
} catch (ex) {
console.log(ex);
}
}, 2000);
}, 2000);
}());
一個問題,我這個看:
例外回調的內部拋出是無用的。是否正確地說,當拋出調用發生時,這些拋出調用超出了範圍,因此這個異常不能被調用並且一直到達頂部?這種例外如何處理?
第二個問題我發現這個嵌套業務可能會非常深入,即使您可以在setTimeout代碼之外保留回調函數代碼,它可能會變得一團糟。
因此,有人可以先澄清一下,如果還有什麼其他問題或者這種編碼的優勢是明顯的嗎?現在
,下面我編寫的程序,做同樣的事情真的,但使用的承諾這一次:
function doWork() {
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// once done resolve promise
res("work done");
}, 2000);
});
}
function goHome(succ) {
console.log(succ);
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// once done resolve promise
res("got home");
}, 2000);
});
}
function cookDinner(succ) {
console.log(succ);
//if exception thrown here it will be caught by chained err handler
throw "No ingredients for dinner Exception!";
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// something went wrong so instead of using throw we reject the promise
rej("No ingredients for dinner!");
// once done resolve promise
}, 2000);
});
}
function goToSleep(succ) {
console.log(succ);
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// once done resolve promise
res("zzz... zz..");
}, 2000);
});
}
doWork()
.then(goHome)
.then(cookDinner)
.then(goToSleep)
.then(function(succ) {
console.log(succ);
}, function(err) {
console.log(err);
});
以前的解決方案相比我看不出有什麼明顯的問題,通過這種方法,除了你顯然必須理解承諾編碼/維護這件事。然而,其優點是:
拋出的異常內部處理程序將被捕獲到進一步鏈接到某處的err處理程序中。
被拒絕的承諾將通過鏈接ERR處理器
的代碼捕獲,是更清潔
現在,我的理解是否正確,或是否有每種方法的任何其他優勢/劣勢?
是的。是。是。我不會擔心後續的維護工作......承諾是ES6草案的一部分,並且有據可查。額外冗長的代價遠遠高於頂級代碼的可讀性。 – spender