假设您有:
function setTimeoutPromise(ms) {
var defer = Q.defer();
setTimeout(defer.resolve, ms);
return defer.promise;
}
然后你有类似的东西:
function foo(ms) {
return setTimeoutPromise(ms).then(function () {
console.log('foo');
});
}
function afterItAll() {
console.log('after it all');
}
foo(100).then(function () {
console.log('after foo');
}).then(afterItAll);
有没有办法修改 foo 以便 afterItAll 在 after foo block 之后执行?例如像这样的东西:
function foo(ms) {
return setTimeoutPromise(ms).then(function () {
console.log('foo');
}).SOMEPROMISECONSTRUCT(function () {
console.log('after it all');
});
}
foo(100).then(function () {
console.log('after foo');
});
我问的原因是我正在开发一个 API,用户可以在其中进行多次这样的 foo 调用,如果 after foo 代码在这些 API 调用后自动执行。我知道我可以使用回调来完成此操作,但我真的很想坚持只使用 promises。
最佳答案
没有,没有。
好吧,让我们看看你在这里问什么:
Is there a way to modify foo so that afterItAll is executed after the after foo block?
这实际上是在问:
Is there any way to know when no more
.then
handlers will be added to a specific promise?
其中,给定一个任意函数,我们可以决定添加一个 fooResult.then(function(){})
作为我们 return
之前程序中的最后一件事从它,所以这就像问:
Is there any way to know when/if a function will return?
将整个程序作为函数给出,就像在问:
Is there any way to know if a program will ever halt?
It's not an easy thing to do至少可以说。此功能不仅不存在,而且在理论上是不可能的。
那我该如何处理呢?
Bergi's answer给你一个很好的主意。我们在 Bluebird 中争取的核心是嵌套。
因为我们想要的东西在一般情况下是不可能的,所以我们必须反转控制,就像回调一样:
function transaction(fn){
// Promise.resolve().then( in ES6/Bluebird promises
return Q().then(function(){
return fn()
}).finally(function(){ // same in Bluebird, in ES6 that's `.then(fn, fn)`
console.log("after it all!");
})
}
这会让你做:
transaction(function(){
return setTimeoutPromise().then(more).then(more);
});
这将运行 setTimeoutPromise,然后是 more
,然后是另一个 more,并在两者都完成后记录“after it all”。这种模式对于数据库驱动程序和资源获取非常有用。
关于javascript - 如何在 q 中的 promise 链的最后执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25975696/