【发布时间】:2014-05-21 17:10:34
【问题描述】:
我编写了相当多的 JavaScript 代码,虽然我认为我确实了解 Promise 的工作原理,但我不确定我是否完全理解 Promise 给 JS 世界带来的优势。考虑下面的代码,简单的异步调用,回调包含更多调用等等。
(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);
}());
我看到的一个问题:
在回调中抛出的异常是没有用的。是否正确地说,当 throw 调用发生时,这些 throw 调用超出范围,因此无法调用异常并且一直冒泡到顶部?如何处理这种异常?
第二个问题我发现这种嵌套业务可能会变得非常深入,即使您可以将回调函数代码保留在 setTimeout 代码之外,它也可能会变得一团糟。
那么首先有人可以澄清一下这种编码是否还有其他明显的问题或优势?
现在,我在下面准备了真正做同样事情的程序,但这次使用了 Promise:
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);
});
与以前的解决方案相比,我认为这种方法没有明显的问题,除了你显然必须了解编码/维护这个东西的承诺。然而,优点是:
在处理程序内部抛出的异常将被错误处理程序捕获,该处理程序被进一步链接到某个地方。
被拒绝的 Promise 将被链式错误处理程序捕获
代码更简洁
现在,我的理解是否正确,或者每种方法还有其他优点/缺点吗?
【问题讨论】:
-
是的。是的。是的。我不会太担心后续的维护...... Promise 是 ES6 草案的一部分,并且有据可查。额外冗长的成本被顶级代码的可读性所抵消。
标签: javascript promise