我对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