【问题标题】:Converting a jQuery Deferred Promise to a Native JavaScript Promise?将 jQuery Deferred Promise 转换为 Native JavaScript Promise?
【发布时间】:2017-01-12 08:25:57
【问题描述】:

我从库中提取了下面这段 JavaScript 代码,它使用了与官方 Promise 规范不同的 jQuerys Deferred/promises。

如果能简单地将这个基本示例转换为原生 JavaScript Promise,同时保持以下相同的格式/结构,我将不胜感激。

我在网上找到的几乎每个 Promise 用法示例都是异步加载某些内容,我在某些情况下想将它们用于其他任务,而这个示例就是这样做的!

  • App.show() 被调用
  • App.show() 调用返回 Promise App.Animations.swipe.apply(this, [current, next, dir]).then(finalize); 的函数
  • promise 函数内部有一个事件处理函数,当 CSS 动画完成并触发 Promise 解析时运行。
  • 当 Promise 解决后,它会调用 finalize 函数内部的 App.show() 函数。

看下面的例子可能更容易理解它的作用......

var App = {

  show: function(index, direction) {
    var $this = this;

    // called after Promise is resolved with .then(finalize)
    finalize = function() {
      // other code here ran now after promise resolved from App.Animations.swipe()....
    };

    // call function which returns a Promise
    Animations.swipe.apply(this, [current, next, dir]).then(finalize);
  },


  Animations = {

    'none': function() {
      var d = UI.$.Deferred();
      d.resolve();
      return d.promise();
    },

    // function returns a Promise which has an event handler inside it that resolves the promise
    'swipe': function(current, next, dir) {

      var d = UI.$.Deferred();

      next.css('animation-duration', this.options.duration + 'ms');

      // Event handler ran one time when CSS Animation ends and triggers the event
      // this event is what resolves the promise
      next.css('opacity', 1).one(UI.support.animation.end, function() {

        current.removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-out' : 'uk-slideshow-swipe-forward-out');
        next.css('opacity', '').removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-in' : 'uk-slideshow-swipe-forward-in');
        d.resolve();

      }.bind(this));

      // return a Promise Object when this function is called
      return d.promise();
    },
  }
};

那么基于该代码如何将其转换为不使用 jQuerys Deferred 并使用 Native JS Promises?

【问题讨论】:

  • 不推荐您在这里要求的内容。 Native Promises 会同化 jQuery Promises,但 jQuery Promises 不会同化原生 Promises。因此,在 jQuery 环境中,低级别的承诺(例如 .swipe())应该返回一个 jQuery 承诺,以确保它被 jQuery 承诺链或调用堆栈中更高的 jQuery.when() 同化。只要.show()(目前写的)是唯一的调用者,你就可以返回一个原生承诺。但是,如果在其他地方调用 .swipe(),您可能会遇到麻烦。

标签: javascript jquery promise jquery-deferred


【解决方案1】:
'none': function() {
  var d = UI.$.Deferred();
  d.resolve();
  return d.promise();
},

这个很简单

'none': function() {
    return Promise.resolve();
},

现在滑动:

'swipe': function(current, next, dir) {
  return new Promise(function(resolve, reject) {
    next.css('animation-duration', this.options.duration + 'ms');

    // Event handler ran one time when CSS Animation ends and triggers the event
    // this event is what resolves the promise
    next.css('opacity', 1).one(UI.support.animation.end, function() {

      current.removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-out' : 'uk-slideshow-swipe-forward-out');
      next.css('opacity', '').removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-in' : 'uk-slideshow-swipe-forward-in');
      resolve();

    }.bind(this));
},

我只想补充一点,jQuery Promises(或者他们称之为 Deferreds)在某个阶段被破坏了,但这些天我认为它们符合 Promise/A+ 规范。

许多jQuery函数(例如ajax,动画)返回一个promise,或者你可以返回.promise() - 这否定了我在答案中所做的需要,那就是使用promise构造函数反模式.

我不太确定你的代码是否知道这些 jQuery 方法是否可以返回一个承诺

【讨论】:

  • 完美 我知道这很简单,但不确定。我在这里做了一个演示,使用 Click 事件来解决 Promise 以供将来参考jsfiddle.net/jasondavis/pjvd39kk 谢谢
  • @JasonDavis - 我刚刚添加了一些可能值得一读的 cmets
  • 谢谢 我会再次阅读 jQuery,因为我检查了那里的承诺状态已经有一段时间了。至于演示,它仅将 jQuery 用于一些单击事件和 dom 选择器,它只是为了获得非异步承诺用法的概念。只是实验!感谢您的帮助
猜你喜欢
  • 2017-01-25
  • 2012-11-03
  • 2019-08-11
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 2017-01-12
相关资源
最近更新 更多