使用 jQuery.Deferred() 重写 ES6 Promise

Rewrite ES6 Promises using jQuery.Deferred()

我目前正在为浏览器编写代码并且仅限于使用 ES5。我确实可以访问 jQuery,并且我需要重写几个当前使用 ES6 promises 的大型函数。例如:

  function getLocationFromIp() {
    return new Promise(function (resolve, reject) {
      $.ajax({
        url: someUrl,
        data: {},
        xhrFields: {
        withCredentials: true
        },
        success: function (data) {
          resolve(data);
        },
        error: function (err) {
          reject(err);
        }
      });
    }).then(transformIpGeoDataToLocation);
  }

我知道我可以访问 .resolve().reject(),但我在实施方面遇到了困难。它看起来像这样吗?

 function getLocationFromIp() {
   return $.Deferred(function (dfr) {
     $.ajax({
       url: someUrl,
       data: {},
       xhrFields: {
         withCredentials: true
       },
       success: function (data) {
        dfr.resolve(data);
       },
       error: function (err) {
         dfr.reject(err);
       }
     });
   }).promise().then(transformIpGeoDataToLocation);
 }

我也在考虑将蓝鸟作为后备方案,但我想尝试一下这种方法,谢谢!不幸的是,Babel 和其他转译器不是一个选项。

因此,如果您不想使用 ES6 promises 而想使用 jQuery promises,函数调用 $.ajax() 已经 return 是 jQuery promise所以没有必要把它包装在另一个承诺中。您可以直接 return $.ajax() 已经 return 的承诺:

  function getLocationFromIp() {
      return $.ajax({
        url: someUrl,
        data: {},
        xhrFields: {
        withCredentials: true
      }).then(transformIpGeoDataToLocation);
  }

注意:在 3.x 之前的 jQuery 版本中,jQuery 承诺(特别是来自 Ajax 调用)不会使用与ES6 承诺会。特别是 jQuery Ajax promise 使用三个参数解析(不是 ES6 标准中的一个)。第一个参数是通常使用的结果。您可以很好地处理它,但需要确保您的 .then() 处理程序(例如 transformIpGeoDataToLocation 知道这一点。

jQuery ajax returns 一个 promise 对象,从 1.8 开始,您可以通过 .then 访问它 请参阅此处的参考资料:http://api.jquery.com/jquery.ajax/

我添加了 some/a 位多余的内容来展示它的工作原理。

function getLocationFromIp() {
  return $.ajax({
      url: someUrl,
      data: {},
      xhrFields: {
        withCredentials: true
      }          
    })
    .done(function(data, textStatus, jqXHR) {
      alert("success");
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
      alert("error");
    })
    .always(function(data | jqXHR, textStatus, jqXHR | errorThrown) {
      alert("complete");
    })
     // combines done/fail, see reference page
    .then(transformIpGeoDataToLocation // gets passed data, textStatus, jqXHR 
      ,
      function(jqXHR, textStatus, errorThrown) {})// fail in then
}

getLocationFromIp().then(somefunctiontocall);