JavaScript 方法链挑战

发布于 2024-08-04 23:29:18 字数 413 浏览 6 评论 0原文

(这个问题并不真正局限于该语言,所以也请随意提交其他语言的解决方案。)

我只是想知道是否可以在 JavaScript 中编写这样的内容:

// Wait 3 seconds and then say our message in an alert box
wait(3).then(function(){alert("Hello World!");});

Where the传统方式是这样写:

// Wait 3 seconds and then say our message in an alert box
setTimeout(function(){alert("Hello World!");}, 3000);

Sorry if这是一个菜鸟问题:p

(This question is not really restricted to the language so please feel free to submit solution in other languages too.)

I was just wondering if it would be possible to write something like this in JavaScript:

// Wait 3 seconds and then say our message in an alert box
wait(3).then(function(){alert("Hello World!");});

Where the traditional way would be to write

// Wait 3 seconds and then say our message in an alert box
setTimeout(function(){alert("Hello World!");}, 3000);

Sorry if this is a noob question :p

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情话已封尘 2024-08-11 23:29:18

你可以很容易地写出来:

function wait(delay) {
  return {
    then: function (callback) {
      setTimeout(callback, delay*1000);
    }
  };
}

wait(3).then(function(){alert("Hello World!");});

如果你想深入了解,我建议你阅读柯里化偏函数应用,这些主题非常有趣。

You can write it easily:

function wait(delay) {
  return {
    then: function (callback) {
      setTimeout(callback, delay*1000);
    }
  };
}

wait(3).then(function(){alert("Hello World!");});

If you want to go in-deep, I recommend you to read about currying and partial function application, those topics are really interesting.

烟火散人牵绊 2024-08-11 23:29:18

另一个版本,没有闭包:

function wait(seconds) {
    if(this instanceof wait)
        this.delay = seconds;
    else return new wait(seconds);
}

wait.prototype.then = function(callback) {
    setTimeout(callback, this.delay * 1000);
};

通过更多代码,您甚至可以重复调用函数:

function wait(seconds) {
    if(this instanceof wait)
        this.delay = seconds;
    else return new wait(seconds);
}

wait.prototype.then = function(callback) {
    setTimeout(callback, this.delay * 1000);
    return this;
};

wait.prototype.wait = function(seconds) {
    this.delay += seconds;
    return this;
};

var start = new Date;
function alertTimeDiff() {
    alert((new Date - start)/1000);
}

wait(1).then(alertTimeDiff).wait(3).then(alertTimeDiff);

Yet another version, without closure:

function wait(seconds) {
    if(this instanceof wait)
        this.delay = seconds;
    else return new wait(seconds);
}

wait.prototype.then = function(callback) {
    setTimeout(callback, this.delay * 1000);
};

With some more code, you can even call the functions repeatedly:

function wait(seconds) {
    if(this instanceof wait)
        this.delay = seconds;
    else return new wait(seconds);
}

wait.prototype.then = function(callback) {
    setTimeout(callback, this.delay * 1000);
    return this;
};

wait.prototype.wait = function(seconds) {
    this.delay += seconds;
    return this;
};

var start = new Date;
function alertTimeDiff() {
    alert((new Date - start)/1000);
}

wait(1).then(alertTimeDiff).wait(3).then(alertTimeDiff);
清风无影 2024-08-11 23:29:18

链接更适合在一个对象上执行多个方法。因此,您宁愿将函数视为对象并在那里设置超时:

Function.prototype.callAfter = function(delay) {
    setTimeout(this, delay*1000);
};

(function(){alert("Hello World!");}).callAfter(3);

Chaining is rather used to execute multiple methods on one object. So you would rather consider the function as the object and set the timeout there:

Function.prototype.callAfter = function(delay) {
    setTimeout(this, delay*1000);
};

(function(){alert("Hello World!");}).callAfter(3);
小耗子 2024-08-11 23:29:18

如果您使用 OO Javascript,那么是的,您可以进行方法链接。

一些流行的 JavaScript 框架就是这样做的。 jQuery 通过为通常不会返回值的函数返回 jQuery 对象来实现此目的。

If you do OO Javascript, then yes, you can do method chaining.

Some of the popular JavaScript frameworks do this. jQuery does this by returning the jQuery object for functions that usually wouldn't return a value.

鱼忆七猫命九 2024-08-11 23:29:18

我刚刚写了一个 小帮手 以某种一致的方式创建这样的 API,也许你喜欢它。

// > npm i mu-ffsm # install node dependency
var mkChained = require('mu-ffsm');

这个想法是通过调用入口函数构建一个具有 S 类型初始状态的流畅构建器。然后,每个链式调用都会将状态转换为新状态。

通过链接一堆调用获得的值可以作为函数执行,该函数调用 exit 来根据该状态和传入的任何选项构造一个值。entry

  • : * ⟶ S
  • transition : (S ⟶ *) ⟶ S
  • exit : S ⟶ (* ⟶ *)

例如

var API = mkChained({
  0:    function(opt)    {return ;/* create initial state */},
  then: function(s, opt) {return s; /* new state */},
  whut: function(s, opt) {return s; /* new state */},
  1:    function(s, opt) {return ;/* compute final value */}
});

所以01分别是入口、出口函数。所有其他函数都会转换内部状态。
所有函数都可以带参数,例如。 opt

我们创建新制作的 API 的一个实例,

var call = API() // entry
   .whut()       // transition
   .then()       // transition
   .whut();      // transition

并调用它

var result0 = call() // exit
  , result1 = call() // exit

看看(小)source 查看这是如何实现的。

附:使用这个答案来更新文档:D

I just wrote a little helper to create APIs like this in a somewhat consistent way, maybe you like it.

// > npm i mu-ffsm # install node dependency
var mkChained = require('mu-ffsm');

The idea is that you construct a fluent builder with some initial state of type S by calling an entry function. Then each chained call transitions the state to a new state.

The value you get from chaining a bunch of calls can be executed as a function, which calls exit to construct a value from that state and any options you pass in.

  • entry : * ⟶ S
  • transition : (S ⟶ *) ⟶ S
  • exit : S ⟶ (* ⟶ *)

For example

var API = mkChained({
  0:    function(opt)    {return ;/* create initial state */},
  then: function(s, opt) {return s; /* new state */},
  whut: function(s, opt) {return s; /* new state */},
  1:    function(s, opt) {return ;/* compute final value */}
});

So 0, 1 are entry, exit functions. All other functions transition an internal state.
All functions can take arguments, eg. opt

We create an instance of our newly crafted API,

var call = API() // entry
   .whut()       // transition
   .then()       // transition
   .whut();      // transition

And call it

var result0 = call() // exit
  , result1 = call() // exit

Have a look at the (small) source to see how this is implemented.

ps. Used this answer to update docs :D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文