如何将jQuery Deferred对象转换为ES6 Promise

33

这是否是将jQuery Deferred 转换为 Promise的正确方法?

var p = Promise.resolve($.getJSON('api/values', null));

还有其他的方法吗?

有哪些限制?我在某个地方读到jQuery延迟不支持异常,所以我假设从延迟创建的承诺也不会支持异常。这是正确的吗?


如果您使用ES6 Promise包装延迟对象,我认为它将支持异常。Promise内部的代码可以是同步和异步的。 - Johan Lindskogen
3个回答

12

我不确定那会不会有效。我建议:

var p = new Promise(function (resolve, reject) {
  $.getJSON('api/values', null)
    .then(resolve, reject);
});

最好您可以创建一个适配器函数,如下:

var toPromise = function ($promise) {
  return new Promise(function (resolve, reject) {
    $promise.then(resolve, reject);
  });
});

var p = toPromise($.getJSON('api/values', null));

有没有一种方法可以完全摆脱jQuery并完成这个操作。对于移动应用程序而言,避免添加jquery.min.js的开销是很好的选择。 - A.Grandt
2
避免使用Promise构造函数反模式,直接使用Promise.resolve - Bergi
@Bergi 你能解释一下这与这里的相关性吗?(最好从jQuery延迟对象提供更好的解决方案到ES6 Promise对象)? - kofifus
1
@kofifus 我的意思是,OP应该继续使用他目前在问题中提供的代码,而不要使用这个答案中建议的代码。这个toPromise函数没有意义,因为它已经作为原生API的一部分存在:它被称为Promise.resolve - Bergi
1
@kofifus 我的意思是,原帖的作者应该继续使用他目前在问题中展示的代码,而不要使用这个答案中提到的代码。这个toPromise函数没有意义,因为它已经作为原生API的一部分存在:它被称为Promise.resolve - undefined
显示剩余3条评论

12

6
请记住,这种方法仅适用于您只对第一个jQuery ajax参数感兴趣,即如果您想要.then(function (data, textStatus, jqXhr) {}),则这种方法将不起作用,因为 Promises 仅支持单个参数。您需要手动将jQuery的“promise”转换为 new Promise(...) 并在其中编排参数。 - nicodemus13

2

我更喜欢组合:

const successCb1 = ()=>$.getJSON('api/values'),
successCb2 = (json)=>alert(json),
errorCb = (e)=>alert(e);
Promise
   .resolve()
   .then(successCb1)
   .then(successCb2)
   .catch(errorCb);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接