以下代码片段是否等效?
版本 1
function doSomething() {
var defer = $q.defer();
foo().then(function() {
bar().then(function() {
defer.resolve();
});
});
return defer.promise;
}
版本 2
function doSomething() {
return foo().then(bar);
}
以下代码片段是否等效?
function doSomething() {
var defer = $q.defer();
foo().then(function() {
bar().then(function() {
defer.resolve();
});
});
return defer.promise;
}
function doSomething() {
return foo().then(bar);
}
这两种方法有很多不同之处。
这两个片段之间的主要区别在于,version 2您将解析的值从foo直接隐式传递到bar. 除此之外,doSomething将解决任何bar将要解决的问题,而version 1结果将被丢弃。
Benjamin Gruenbaum 提出的一些其他重要观点:
(a) 如果 bar 是参考错误,则 1 拒绝内部承诺并 2 抛出。
(b) 1 需要对 $q 的引用,其中 2 与实现无关。
(c)版本 1 不是异常安全的,拒绝将被吞下,而版本 2 会让您 .catch 拒绝。; 还有几个较小的差异。请参阅 stackoverflow.com/questions/22539815
你也可以这样写。
这样,您就不会从footo获得已解析值的隐式传递槽bar(它现在是显式的),这可能会令人困惑或容易被忽略。foo如果您想对已解析的值或bar在返回它们之前执行某些操作,它也很有用。
function doSomething() {
return foo().then(function(res){
// maybe do something with the result of foo
return bar(res);
}).then(function(res){
// maybe do something with the result of bar
return res;
});
}
手动创建延迟对象应保持在最低限度,通常是一种反模式。
https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern
这里演示的关键原则是,promise 将在其 resolve 方法中采用返回的 promise(或 thenable)的状态。