以下代码片段是否相同?
版本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); }
解决方法
这两种方法之间存在许多差异.
两个片段之间的主要区别在于,在版本2中,您隐式将已解析的值从foo直接传递到bar.
除此之外,doSomething将解析任何bar将解析的内容,而在版本1中,结果将被丢弃.
Benjamin Gruenbaum提出的一些重要观点:
(a) if bar is a reference error 1 rejects the inner promise and 2
throws.
(b) 1 requires a reference to $q where 2 is implementation
agnostic.
(c) version 1 is not exception safe and a rejection will be
swallowed where version 2 will let you .catch a rejection. ; There are
several smaller differences as well. See
stackoverflow.com/questions/22539815
你也可以这样写.
这样你就不会得到从foo到bar的解析值的隐式传递槽(现在它是显式的),这可能会令人困惑或容易被忽视.如果您想在返回foo或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将在其解析方法中采用返回的promise(或者thenable)的状态.