javascript - 如何在 q 中的 promise 链的最后执行代码

标签 javascript promise q chaining

假设您有:

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 以便 afterItAllafter 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/

相关文章:

node.js - Promisify游标执行: MongoDB Native Driver

javascript - 通过测试可能未处理的错误

angularjs - AngularJS 的 $q.all 仅适用于一个结果

javascript - 在回调 AngularJS ng-click 样式中执行 fn(param1, param2)

javascript - nodejs : API differences fs. readFile 与 http.get

javascript - Greasemonkey 脚本中的 XPath 未在 XHTML 页面上选择正确的节点

javascript - 显式脚本结束标记始终转换为自闭合

javascript - 有选择地支持某些浏览器

javascript - AngularJS:操作 `query` 的资源配置错误。预期响应包含一个对象,但得到一个数组

javascript - 根据 promise 值返回结果