0

我有一个对象,其值来自 AJAX 请求。我正在将它转换为一个承诺,并且遇到了一些我不期望的承诺行为。我在这里有一个示例,它表现出相同的行为,但我用 Q.all() 代替了我的 AJAX 请求。

(Thing = function(){
  var promise;
  var refresh = function() {
    promise = Q.all(["a", "b"]);
  };

  var fetch = function(i) {
    return promise.then(function(promiseVal){
      return promiseVal[i];
    });
  };

  refresh();

  return {
    "fetch": fetch,
    "refresh": refresh,
    "promise": promise
  };

}());

事物在加载时执行并运行“刷新”以最初填充自身。“fetch”函数的重点是我的异步请求(在这种情况下为 Q.all)返回一个数组的承诺,但我真正想要的是数组中元素的承诺(例如“a”的承诺或对“b”的承诺)。所以我期待Thing.fetch(1)为“b”返回一个承诺。

Thing.fetch(1)确实返回了一个承诺,但如果我这样做Thing.fetch(1).valueOf()了,它会返回一个承诺,而不是我所期望的“b”。如果我做:

Thing.fetch(1).then(function(foo){
  console.log(foo);
});

它将在控制台上打印“b”。

如果我这样做Thing.promise.valueOf(),它会返回数组,所以当我调用“fetch”时,promise 就解决了。

所以我的问题是,当我在“fetch”返回的承诺上调用 valueOf() 时,为什么不返回一个值?

4

2 回答 2

0

看来你的承诺还没有解决。

它没有很好的文档记录,但分散在我发现的 wiki 页面中:

valueOf 调用默认返回 Promise 本身。

valueOf方法对于在事件循环的同一轮中提供有关 Promise 的信息很有用。例如,已解决的承诺返回它们的解决值,而拒绝返回一个被 isRejected 识别的对象。

如果 promise 被履行,则promise.valueOf()返回履行的价值。如果承诺是或已经转发到延迟承诺,它返回最近的延迟承诺。对于被拒绝的承诺, promise.valueOf()返回一个哨兵对象 {rejectedPromise: true, reason: {}}

当你这样做Thing.fetch(1).then(console.log);时,它当然会"b"在控制台上打印 - 这是传递给回调的解析值。但请注意,它将来会调用日志函数!

于 2013-07-18T21:45:56.957 回答
0

因为 promise 的值是一个数组。传递给“then”的函数的值将是某个值。您的 fetch 方法并没有真正返回一个承诺,它正在解决一个承诺。

于 2013-07-18T21:54:58.320 回答