Why does Underscore.js have a delay function?

13,632

Solution 1

It's a cross browser way of being able to pass extra arguments which will appear as the arguments to the callback, like setTimeout(). This doesn't work in IE.

It can make your code prettier...

setTimeout(_.bind(function() { }, null, "arg1"), 1e3);

...vs...

_.delay(function() { }, 1e3, "arg1");

I agree that it's one of the less useful Underscore methods, which are outlined in Naomi's answer.

Solution 2

Why does Underscore.js have a delay function?

Because dumb. This particular underscore.js method seems pretty stupid.

Cons

  1. additional function in lib means larger code base
  2. larger code base means more to maintain and more possible bugs
  3. code that uses this function now has a dependency on that lib
  4. lesser/nil improvement over native API means low cost:gain ratio
  5. new apis to learn

Pros

this section intentionally left blank


I would just learn to use javascript and do something like

var hello = function() {
  console.log("hello");
};

var delay = 1000;

window.setTimeout(hello, delay);

Simple, right? Underscore.js is sometimes pretty useless. Honestly, window.setTimeout is perfectly useful just the way it is.


Here's another example to show how to pass an arg to the function

var Cat = function(name) {
  function meow(message) {
    console.log(name, "says meow!", message);
  }
  this.meow = meow;
};

var duchess = new Cat("Duchess");

window.setTimeout(duchess.meow.bind(duchess, "please feed me!"), 2000);

// 2 seconds later
// => Duchess says meow! please feed me!

If you can't depend on .bind you can use a closure too

window.setTimeout(function() {
  duchess.meow("please feed me!");
}, 1000);

Wow, that was difficult, though. I'm going back to underscore and lodash and jquery. This JavaScript stuff is tough !

Solution 3

aes·thet·ics

The author of that library, who chose to spend his/her spare time to open source it, talk about it, use it as a way to introduce people to javascript and perhaps get someone to have a light-bulb moment around closure scope thought the library's attractiveness was enhanced by having this.

Arguing the relevancy of this function in isolation is like arguing the relevancy of a painting or other piece of craftsmanship. Some may like it, others may not.

You are free to like it or not. I, personally, prefer just-get-to-the-point libs.

_.delay, _.defer, _.throttle, _.after have a flow IMHO that reads better than window.

On-top of this, generally I also like writing node server side (nodejs) and not have to shift/in/out of mode... try using window.timeout in node and see what happens.

Solution 4

Not much, although it fits thematically with defer, debounce, and so on. This means you can use the underscore wrapping notation:

_(yourfunction).delay(1000);

Also it doesn't seem like it will let you get away with a string argument, which would call eval.

Share:
13,632

Related videos on Youtube

Aadit M Shah
Author by

Aadit M Shah

Computer science engineer with over ten years of experience in software development. Implemented web development, web analytics, and information technology solutions for both Cloud 100 and startup companies. Contributed to several open source software projects, with over 1.2 million aggregate downloads.

Updated on October 18, 2022

Comments

  • Aadit M Shah
    Aadit M Shah over 1 year

    This is the source code for Underscore.js' delay function:

    _.delay = function (func, wait) {
        var args = slice.call(arguments, 2);
        return setTimeout(function () { return func.apply(null, args); }, wait);
    };
    

    How is this any different from setTimeout? Why does Underscore.js need delay?

  • Aadit M Shah
    Aadit M Shah almost 11 years
    Internet Explorer doesn't support callback arguments. What a b****!
  • Aadit M Shah
    Aadit M Shah almost 11 years
    I don't think anybody in their right mind would pass a string to setTimeout.
  • RobG
    RobG almost 11 years
    @Alex—it doesn't support passing a string literal as the first parameter, so not that cross browser. Perhaps that's mentioned in the documentation…
  • user3167101
    user3167101 almost 11 years
    @RobG Well, I don't think that's a feature we want to keep :)
  • RobG
    RobG almost 11 years
    @plynx—not necessarily eval, it might instead use the Function constructor. ;-) @Aadit—not hard to support strings too, just test the first argument and if it's a string, use the Function constructor, then call set timeout with that.
  • Mulan
    Mulan almost 11 years
    @RobG and why would you want to call a function based on a string? Never mind, if your javascript doesn't work, just wrap it in an additional $() call.
  • Mulan
    Mulan almost 11 years
    @alex, I don't think this has anything to do with cross browser compatibility. It's just a convenience function for people that doesn't really have a purpose in the first place if you simply understand how to use javascript's native .bind, .call, or .apply functions.
  • user3167101
    user3167101 almost 11 years
    @naomik You could say the same about a lot of Underscore functions.
  • Mulan
    Mulan almost 11 years
    @alex, then maybe don't say something about "cross browser" when that's completely not true or relevant.
  • user3167101
    user3167101 almost 11 years
    @naomik How is it irrelevant? Underscore provides (among other things) missing functionality that isn't in all browsers. Here is another example that allows passing additional arguments to be passed to the callback. That isn't supported in IE. It's a possible reason why this function exists.
  • Mulan
    Mulan almost 11 years
    @alex, _.delay does not provide extra functionality; in fact, it provides less if you consider the fact that there's no way to set the context for the function you want to delay. (See my answer for more details about context). True, setTimeout doesn't behave identically in every browser, but you can pass the additional arguments using .bind like you should be doing in the first place.
  • user3167101
    user3167101 almost 11 years
  • RobG
    RobG almost 11 years
    @naomik—mine is not to reason why, just to comment. ;-) I might pass a string to setTimeout if it was something trivial like alert('boo'). But then I can also do setTimeout(Function('…'),…), so what is gained by not supporting strings?
  • RobG
    RobG almost 11 years
    I understand your approach, however once you start down the road of a general library, you soon find yourself wrapping everything so as not to expose the underlying API (e.g. jQuery wraps everything under the sun). Otherwise, users start get confused over what is the library and what is native JS or DOM or whatever you're abstracting. Not supporting one approach over the other, just saying.
  • Plynx
    Plynx almost 11 years
    @AaditMShah robg You both seem to be misunderstanding me—I'm referring to the benefit of not accepting string arguments. I've seen it happen lots of times, and even sometimes by accident. You can find many examples in code here on StackOverflow. Programmer's hands are strange things and sometimes they put quotes around things when you're not looking.
  • Aadit M Shah
    Aadit M Shah almost 11 years
    @Plynx - I understand you. I also understand that delay is safer because you can't pass it a string argument. I still think that nobody in their right mind would pass setTimeout a string. You make it sound almost comical by saying, "programmers' hands are strange things and sometimes they put quotes around things when you're not looking." Next time you see the work of those hands please let them know that I think that they should consult the brain before playing dangerous games. Also you forgot to put an at sign before mentioning @RobG.
  • Plynx
    Plynx almost 11 years
    @AaditMShah Thanks. I didn't forget, but the comment system informed me that I can only put one mention, which seems to me like a strange restriction. As for no one in their right mind doing such a thing, it's an academic argument. I could say I agreed with you but it wouldn't change the fact that programmers are out there every day doing it, for whatever reason, even programmers who know to avoid eval on user data, whether due to inexperience in JS syntax or supporting legacy code, whatever. For this reason it's not allowed in Javascript's strict mode.
  • Mulan
    Mulan over 9 years
    Bunch of noobs still down-voting this. Keep 'em coming, rookies :)
  • Aadit M Shah
    Aadit M Shah over 9 years
    I don't understand all the hate. You don't deserve to be downvoted.
  • Mulan
    Mulan over 9 years
    @RobG I disagree. I don't think a lib's goal should be to completely replace all the native functionality of a language. Even if it's a utility library, it should maintain a clear focus on things it's actually improving upon. In this case, _.delay is not enough of an improvement (or an improvement at all) to warrant the abstraction and additional API to memorize.