请问这种 队列形式 的 链接调用 如何实现?
发布于 10 年前 作者 think2011 3698 次浏览 最后一次编辑是 8 年前

希望达到的调用方式如下

login.verify().pass(function(){ alert('通过了') }).fail(function(){ '没通过' });

首先在verify()中经过认证,如果通过了执行pass(),如果没通过,执行fail()。

这里是一个模板。

var login = {
  verify: function() {
    // 这里的代码如何写?
    return this;
  },
  
  pass: function(fn) {
    fn();
  },
  
  fail: function(fn) {
    fn();
  }
};

13 回复

想了个办法,不知道有没有更好的实现方式。

coffeescript

login =
  verify: ->
    @result = true
    return @

  pass: (fn) ->
    if @result then fn()
    return @

  fail: (fn) ->
    unless @result then fn()

javascript

var login;

login = {
  verify: function() {
    this.result = true;
    return this;
  },
  pass: function(fn) {
    if (this.result) {
      fn();
    }
    return this;
  },
  fail: function(fn) {
    if (!this.result) {
      return fn();
    }
  }
};

试试Promsie。还有为什么要写成这么难看的代码?

@ngot 如果不用promise,应该怎么写?

链式调用的接口不是这么设计滴,就Promise不好吗

login.verify().then (passed) ->
  message = if passed then '通过了' else '没通过'
  alert message

@think2011 我来替楼上回答:fibjs

@ravenwang 谢谢,我去研究下。

@ravenwang 其实,这句,我忍住,没说。

这样吧,把 login 设计成一个类:

Login.prototype.verify;
Login.prototype.pass;
Login.prototype.fail;

然后继承自 EventEmitter

在这三个函数里面最后都要 return this

Login.prototype.verify = function() {
    if(验证成功) this.emit("succ");
    if(失败) this.emit("fail");

    return this;
};

然后另外两个函数所要做的事情实际上就是:

Login.prototype.pass = function(cb) {
    this.on("succ", cb);
    return this;
}

这样就能完成你所说的链式调用了。

@XadillaX 当然也可以不用继承,直接在 Login 的构造函数里面加一个 this.emitter = new EventEmitter(),然后其他函数里面就是 this.emitter.[emit|on] 了。

@XadillaX 恩,这个办法很合适! 可是只有 node.js才有 EventEmitter类的吧?

这个链式调用接口设计本身是有问题的,接口之间通常应该是独立不相互依赖的,这个接口设计中passfail需要依赖verify,况且一个if...else就能解决的问题干嘛要搞个链式调用

@ravenwang 我有一个需求是这样的,拿商城作例子吧。 正常情况下用户去浏览商品,当要下单,或者浏览自己的订单的时候,才需要登录。 所以接口打算这样设计。 根据verify()来确定是弹出登陆框(fail)还是进入对应功能(pass)。

请问,就以上的需求,有更好的设计逻辑吗?

@think2011

login.verify(function (passed) {
    if (passed) {
      onPass();
    } else {
      onFail();
    }
});

/////

login.verify(
  function onPass() {
  },
  function onFail() {
  }
);
回到顶部