【问题标题】:Q promise. Difference between .when and .thenQ承诺。 .when 和 .then 之间的区别
【发布时间】:2014-09-02 12:59:49
【问题描述】:

我虽然这段代码可以工作:

var promise = function(val) {

    var _val = val;

    return setTimeout(function(_val) {

        var newVal = val / 10;

        return {
            newVal : newVal,
            message : 'it just to be a ' + val
        };
    }, 3000);
};

Q.when(promise(400)).then(function(obj) {
    return console.log('jaaaaj !', obj);
}, function() {
    return console.log('no yet...');
});

JSFiddle

我的想法是:当 setTimeout 在四秒后完成它的工作时,Q 库将在第一个回调中捕获返回并显示具有两个属性的对象:newVal : 4message : 'it just to be a ' + 400。相反,我在成功回调中有奇怪的 1 数字作为 obj...

顺便说一句,Q 库中的 .when.then 有什么区别?

【问题讨论】:

  • 您实际上无法从setTimeout 返回任何内容,因为它是异步的。此外,从上下文(以及接受的参数)中应该清楚when 包装了一个承诺,以便它可以与then 链接,then 承诺解决时触发回调。

标签: javascript promise q


【解决方案1】:

.when() 接受一个或多个 Promise 作为参数。您正在向它传递一个计时器句柄,因此它会立即执行 .then() 处理程序。

.when() 没有神奇的能力来辨别你传递给它的东西何时完成。您必须向它传递一个或多个承诺,并且它会监控这些承诺何时解决。

此外,您不能从 setTimeout() 返回任何内容,但如果您在 setTimeout() 中解析了一个承诺,您可以将数据传递给 .resolve() 方法。

你可以这样做:

var promise = function(val) {
    var defer = Q.defer();

    setTimeout(function() {

        var newVal = val / 10;

        defer.resolve({
            newVal : newVal,
            message : 'it just to be a ' + val
        });
    }, 3000);

    // return the promise
    return defer.promise;
};

Q.when(promise(400)).then(function(obj) {
    return console.log('jaaaaj !', obj);
}, function() {
    return console.log('rejected...');
});

但是,当你只有一个承诺时,你甚至不需要Q.when()。你可以这样做:

promise(400).then(function(obj) {
    return console.log('jaaaaj !', obj);
}, function() {
    return console.log('rejected...');
});

【讨论】:

  • "你不能从 setTimeout() 返回任何东西" - 正确,但同样,你不能将任何东西传递给 setTimeout。在 setTimeout 的函数内使用的任何对象/值必须是“自生成的”(例如 var foo = 99;)或取自编写函数(但不一定是 setTimeout 本身)的词法环境。因此setTimeout(function(_val) {可以改写为setTimeout(function() {,而var _val = val;行可以删除,因为val可以从setTimeout的函数内部自动到达(如var newVal = val / 10;行所示)。
  • 哦,是的,使值/对象可用于 setTimeout 函数的第三种方法是使用Function.prototype.bind(),它返回一个带有“预传递”参数(和上下文)的新函数。
  • @Roamer-1888 - 你没有将参数直接传递给setTimeout() 回调是正确的。我最初在 OP 的代码中没有看到这一点,但对他们来说幸运的是,他们没有使用他们声明的论点。无论如何,我已将其从答案中的代码中删除。在这种情况下,不需要向它传递任何东西,因为它可以直接访问父范围以获取val。是的,可以使用.bind(),尽管在本例中不需要这样做。
  • jfriend00,很抱歉闲聊。如果我能更简洁地表达自己,我相信你会明白这一点。 (而且我不赞成编辑其他人的答案)
  • 谢谢你们。现在对我来说清楚多了。也许你知道一些值得推荐的关于 Promise 的好教程?
猜你喜欢
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-16
  • 2015-08-15
相关资源
最近更新 更多