在 jQuery 中使用 .then() 链接 promises/Deferreds

Chaining promises/Deferreds with .then() in jQuery

我正在使用 jQuery 1.8.3 我有一个 returns 新 jQuery.Deferred() 的功能。根据文档,当我使用 deferred.then() 链接调用此函数时,我希望在前面的函数 returns 时调用给定函数,并接收 jQuery.Deferred() 作为输入。

实际上,当前一个函数的 jQuery.Deferred() 收到 deferred.resolve() 信号并接收传递给 .resolve() 的值时,将调用给定函数。

实际行为是我想要的,但我担心我依赖于 undocumented/unsupported 行为,或者我实际上有一个 bug 造成了我想要的错觉。

例如给定

function async_task(i) {
  console.log("Starting async_task(" + i + ")\n");
  var def = $.Deferred();
  setTimeout(function() {
    console.log("    finished " + i + "\n");
    def.resolve(i + 1);
  }, 1000);
  return def;
}

console.log("starting\n");
var p;
p = async_task(1);
p = p.then(async_task);
p = p.then(async_task);
p.then(function() {
  console.log("done\n");
});

输出是

starting
Starting async_task(1)
    finished 1
Starting async_task(2)
    finished 2
Starting async_task(3)
    finished 3
done

但我希望

starting
Starting async_task(1)
    finished 1
Starting async_task(2)
Starting async_task([object Object])
done
    finished 2
    finished [object Object]

我当然可以想象 jQuery 正在探测函数传递给 .then() returns 的内容,如果它是 deferred/promise 做我想做的,但我可以'找到支持该想法的文档。

为什么我基于文档的期望与我观察到的不一致?我是否忽略了文档?这是我不应该依赖的无证行为吗?我真的有错误吗?

看来您只是误读了 docs。不可否认,它们可以写得更好。

你漏掉的句子是

These filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks.

虽然 jQuery 没有很好地解释,但这种采用("unwrapping")进一步的承诺实际上是杰出的 features of promises