Ember/RSVP 传递给 resolve() 时 Promise 值发生变化

Ember/RSVP Promise value changes when passed to resolve()

我正在尝试将 jQuery AJAX 请求包装在 Ember RSVP 承诺中,但我遇到了这个问题,我发送给 resolve 函数的值(这是 jqXHR 参数)从 object 更改为 string

做请求+创建请求的代码如下:

return new Ember.RSVP.Promise(function(resolve, reject) {
  Ember.$.ajax([URL], {
    type: 'POST',
    dataType: 'text'
  }).then((data, textStatus, jqXHR) => {
    console.log(jqXHR);
    resolve(jqXHR);
  }, (jqXHR, textStatus, errorThrown) => {
    resolve(jqXHR);
  });
});

在我的控制器中,我这样处理请求:

promise.then((response) => {
  console.log(response);
  if (response.status === 200) {
    something...
  } else {
    something else...
  }
  receipt.set('busy', false);
});

现在,根据我对 RSVP.Promise 的基本(可能还有缺陷)理解,resolve(jqXHR) 应该 发送 jqXHR对象作为回调的参数,对吗?

问题是,当我在控制台打印 response 时,我得到的只是 200 success,这是我执行的 HTTP 请求的主体。

然而,当我在解析它之前打印 jqXHR 时,它正确地打印了整个对象:

Object {readyState: 4, responseText: "200 success", status: 200, statusText: "OK"}

那么为什么会这样呢? Ember 是在做一些奇怪的黑魔法并将 jqXHR 对象转换为字符串吗?还是发送的 data 字符串代替了我期望的 jqXHR 对象?

谢谢!

知道了!

好吧,显然 rsvp.js 检查发送到 resolve 方法的对象是否是 'thenable'(可读),即它是否包含 then方法。

如果是'thenable',会执行对象的then方法,取它的第一个参数(只),作为fulfilled值。这个小魔法允许链接解析,但不能很好地处理带有多个参数的回调。

所以在我的例子中,我发送了 jqXHR 来解决,它确实包含一个 then 方法(根据 jQuery documentation)。 RSVP 然后尝试实现 jqXHR 对象作为承诺,并返回 resolve 回调的第一个参数。

现在,jqXHR 解析回调的签名是 function(data, textStatus, jqXHR);,这就是为什么发送到我的回调的对象不是我预期的 jqXHR,而是 jqXHR解析回调:data.

TL;DR:检查您尝试用来解决承诺的对象是否具有 then 方法,因为它将被执行。