【问题标题】:How can I test if a function is returning a promise in Ember?如何测试函数是否在 Ember 中返回承诺?
【发布时间】:2015-03-30 14:35:53
【问题描述】:

在 Ember 中,我有时会遇到需要检查函数是否返回 Promise 的情况。例如,如果我有一个派生的路线:

MyRoute = ParentRoute.extend({
  beforeModel: function() {
    this._super().then(function() {
      // do something...
    });
  }
});

虽然 beforeModel 可以返回一个 Promise,但它可能不会。特别是,如果它是默认的 Ember.K 实现,那么它不会。我宁愿不总是这样做:

var res = this._super();
if (typeof res.then === "function") {
  res.then(function() {
    // do X
  });
} else {
  // do X
}

我认为有一种方法可以包装一些人们不知道它是否是 thenable 的东西,然后不管它是链式的。但我在文档中找不到。

上面的内容是不受欢迎的,因为它很冗长,并且需要两次 X 的代码。

想法?

更新:

我能够通过以下咖啡脚本测试确认 @torazaburo 的回应:

`import { test, module } from 'ember-qunit'`

module "testing promise behavior"

test "can cast to promise", ->
  expect 3
  order = []
  returnsPromise = ->
    new Ember.RSVP.Promise (resolve) ->
      order.push 'a'
      resolve('response 1')
  returnsValue = ->
    order.push 'b'
    'response 2'

  Ember.run ->
    Ember.RSVP.resolve(returnsPromise()).then (response) ->
      order.push 'c'
      equal response, 'response 1'
    Ember.RSVP.resolve(returnsValue()).then (response) ->
      order.push 'd'
      equal response, 'response 2'

  equal order.join(' '), 'a b c d'

感谢您的解决方案!似乎 RSVP 的 Promises 实现也有一个内置的 resolve 方法,可以执行您的建议,结果与您建议的 cast 相同,尽管现在已弃用。

【问题讨论】:

    标签: ember.js rsvp.js


    【解决方案1】:

    可能还有其他更好的方法可以做到这一点,但您可以这样做:

    function ensurePromise(x) {
        return new Ember.RSVP.Promise(function(resolve) {
            resolve(x);
        });
    }
    

    如果x 不是一个promise,那么这将返回一个已经用该值实现的promise,然后你可以挂起then。如果x 一个承诺,那么它会返回一个假设其状态(包括已解决/拒绝状态和值/原因)的承诺。

    这在原生 Promises 中等价于

    Promise.resolve(x)
    

    所以在你的情况下,

    MyRoute = ParentRoute.extend({
        beforeModel: function() {
            ensurePromise(this._super()).then(function() {
                // do something...
            });
        }
    });
    

    但是请注意,这可能会将同步值转换为异步值(承诺)。但是,通常认为在某些情况下具有同步行为而在其他情况下行为异步的函数是不好的做法。所以看起来没问题,如果我们有一个可能是同步异步的值,将其强制为始终异步的东西。

    我相信在过去的某个版本中,曾经有一个叫做 RSVP.Promise.cast 的东西,我记得好像做过大致相同的事情,但我现在无法找到它。

    【讨论】:

      猜你喜欢
      • 2018-07-27
      • 2017-04-07
      • 2016-12-18
      • 1970-01-01
      • 2016-10-04
      • 2017-05-26
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      相关资源
      最近更新 更多