我想知道是否有可能重构这个伪代码:
function foo() {
if (condition) {
return somethingReturningPromise().then(function (data) {
doSomethingOnSuccess(data);
return mainFunctionReturningPromise(); // here ...
}, function () {
return mainFunctionReturningPromise(); // here ...
});
}
return mainFunctionReturningPromise(); // and here !!!
}
// ... somewhere ...
foo().done(function () {
// here, mainFunctionReturningPromise successfully resolved
continueProgram();
});
如您所见,在所有可能的情况下都会调用mainFunctionReturningPromise
:
somethingReturningPromise()
成功somethingReturningPromise()
失败由于doSomethingOnSuccess(data)
提供了特殊处理,我似乎无法找到重构mainFunctionReturningPromise
的3次调用的方法。你能吗?
答案 0 :(得分:1)
寻找可读性和可理解性,我可能会选择这样的东西:
function foo() {
if (condition) {
return somethingReturningPromise().then(doSomethingOnSuccess, function(err) {
// log, but ignore error
console.log(err);
return $.when(); // return resolved promise to flip state to resolved in older versions of jQuery
}).then(mainFunctionReturningPromise);
} else {
return mainFunctionReturningPromise();
}
}
这会在两个地方调用mainFunctionReturningPromise()
,但我认为它可以优化以便于遵循逻辑。
如果您只想在一个地方拨打mainFunctionReturningPromise()
,可以这样做:
function foo() {
var p = $.when(); // shortcut to get a resolved promise in jQuery
if (condition) {
p = p.then(somethingReturningPromise).then(doSomethingOnSuccess, function(err) {
// log, but ignore error
console.log(err);
return $.when(); // return resolved promise to flip state to resolved in older versions of jQuery
});
}
return p.then(mainFunctionReturningPromise);
}
jQuery承诺的一个恐怖是使用jQuery 1.x和2.x,为.then()
的第二个参数提供处理程序不遵循Promise规范并且不会更改要解析的承诺。您必须显式返回已解析的promise或promise,这些promise最终将解析以使catch处理程序执行其正确的工作。这已在jQuery 3.x中修复。这就是为什么来自catch处理程序的return $.when();
来确保promise转换到已解析状态,从而继续使用所有jQuery版本中的其他.then()
处理程序。
仅供参考,在这里使用$.when()
并没有什么神奇之处。这只是我知道在jQuery中获得解决的承诺的最短路径。比$.Deferred().resolve().promise()
更短的方式,这将是jQuery中的教科书方式。
答案 1 :(得分:0)
catch
处理程序,它只是忽略错误,然后将一个mainFunctionReturningPromise
调用链接到它else
分支也会返回一个空的,已履行的承诺,以便您可以将mainFunctionReturningPromise
链接到它
function foo() {
var p = condition
? somethingReturningPromise().then(function(data) {
doSomethingOnSuccess(data);
return undefined;
}, function(err) {
// ignore error
return undefined;
})
: $.Deferred().resolve(undefined).promise();
return p.then(mainFunctionReturningPromise);
}
(可以省略undefined
s,我只是将它们包括在内以明确mainFunctionReturningPromise
参数)
答案 2 :(得分:0)
要使<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" value="Click" class="item-blog" />
<input type="button" value="Reset" class="item-blog-reset" />
出现一次,它必须是承诺链末尾的mainFunctionReturningPromise
回调。
为了保证.then()
可用,无论.then()
的结果如何,您都需要保证承诺。
这可以通过多种方式实现。
一种有趣的方式是将内部代码转换为#34;。从已解决的承诺(jQuery中的if (condition)
)开始,并在链式$.when()
中执行下游决策(if (condition){...}
)。
.then()