I'm not aware of a published implementation of this technique, but it's a fairly standard way of using promises. An interesting side effect of the composability, reusability, and extensibility of functional programming is that often you don't find things in libraries that you would expect.
In a less composable paradigm, you would need support in a library to do something like your throttle function, because you have to weave support for it throughout other functions. In functional code, programmers just write it themselves once, then they can reuse it everywhere.
After you write something like this, who do you share it with, and how? It's too small to be its own library. It's a little too specific to not be considered bloat in a promise library. Perhaps some sort of promise utilities library, but then it would be in a not very cohesive module with other functions vaguely related to promises, which makes it hard to find.
What happens to me a lot is I search for 10 minutes or so, then just write it myself because it would only take me a half hour. I put it in a "utilities" file I keep around with other odds and ends functions that are short but highly reusable, but don't really fit anywhere. Then six months later I happen upon it by chance in a community-maintained library with some weird name.
My point is, with functional programming, not being able to find an existing implementation for something that feels fairly "standard" is not a sign that other people are either doing it in a superior way, or that you're the first to come up with it. It's just a symptom of the difficulty of sharing short, reusable code in a way that's easy to discover by a search.
Doug Crockford discusses let
at this point in his talk, "The Better Parts".
The point is, let
avoids a source of misunderstanding, esp. for programmers with expectations set by languages with block-scope. A var
has function scope (it declares a variable that's visible throughout the function) even though it looks like it has block scope.
var
might possibly still be useful in an extreme case like machine-generated code, but I'm stretching hard there.
(const
is also new and has block scope. After let x = {'hi': 'SE'}
you can reassign to x
, while after const y = x
you cannot reassign to y
. That's often preferrable since it keeps something from accidentally changing out from under you. But to be clear, you can still modify the object y.hi = 'SO'
unless you freeze it.)
Realistically, your impression is right on for ES6: Adopt let
and const
. Stop using var
.
(In another performance of "The Better Parts", Doug says why ===
was added rather than fixing the problems of ==
. ==
produces some "surprising" results, so just adopt ===
.)
A Revealing Example
Mozilla Developer Network gives an example where var
does not work as intended. Their example is a realistic one that sets onclick
handlers in a web page. Here's a smaller test case:
var a = [];
(function () {
'use strict';
for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
a.push( function() {return i;} );
}
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]
// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]
var
trips us up because all loop iterations share the same function-scoped i
variable, which has the value 5
after the loop finishes.
Another Telling Example
function f(x) {
let y = 1;
if (x > 0) {
let y = 2; // `let` declares a variable in this block
}
return y;
}
[f(1), f(-1)] // --> [1, 1]
// Start over, but change `let` to `var`.
// --> [2, 1]
let
declares block-scoped variables.
var
confuses us by referring to the same variable throughout the function.
Best Answer
This is an absolutely sensible use of promises. Its one of the primary ways that promises are intended to be used.
The way that promises can have .then() added before or after being resolved is directly to allow this kind of usage. The point is that you might have the value right away, or it might not show up until some time later. In either case, the promise api runs the same way.
On the side, your code can be simplified
Or using lodash or underscore