Why can't Promise.resolve be called as a function?
Something that overhears me and my colleague. Consider the following ...
const {map, compose} = require('ramda');
compose(
console.log,
map(Math.tan)
)([1,2,3]);
compose(
console.log,
map(v=>Promise.resolve(v))
)([4,5,6]);
compose(
console.log,
map(Promise.resolve)
)([7,8,9]);
As you would expect, header 1, 2, and 3 are outputted, as well as resolving promises 3, 4, and 5. But my question is, why the third soce? Why doesn't Promise.resolve behave like any other function?
[ 1.5574077246549023, -2.185039863261519, -0.1425465430742778 ]
[ Promise { 4 }, Promise { 5 }, Promise { 6 } ]
/home/xxx/node_modules/ramda/src/internal/_map.js:6
result[idx] = fn(functor[idx]);
^
TypeError: PromiseResolve called on non-object
at resolve (<anonymous>)
at _map (/home/xxx/node_modules/ramda/src/internal/_map.js:6:19)
at map (/home/xxx/node_modules/ramda/src/map.js:57:14)
at /home/xxx/node_modules/ramda/src/internal/_dispatchable.js:39:15
at /home/xxx/node_modules/ramda/src/internal/_curry2.js:20:46
at f1 (/home/xxx/node_modules/ramda/src/internal/_curry1.js:17:17)
at /home/xxx/node_modules/ramda/src/internal/_pipe.js:3:27
at /home/xxx/node_modules/ramda/src/internal/_arity.js:5:45
at Object.<anonymous> (/home/xxx/b.js:20:6)
at Module._compile (module.js:569:30)
source to share
Promise.resolve
refers to a function resolve
without a context object.
You want to call it with the appropriate context object. It can be done
- by calling it on that context object as in
v => Promise.resolve(v)
, or - creating a linked version like in
Promise.resolve.bind(Promise)
So this would work:
compose(
console.log,
map(Promise.resolve.bind(Promise))
)([7,8,9]);
Remember Javascript has no classes. Functions have no owner. Objects can store functions in their properties, but this does not mean that the function belongs to that object.
Another way is to explicitly set the context object using Function#call
either Function#apply
:
function (v) {
var resolve = Promise.resolve;
return resolve.call(Promise, v);
}
This is perhaps best illustrated by focusing on something other than a method:
function Foo() {
this.bar = {some: "value"};
this.baz = function () { return this.bar; };
}
var f = new Foo();
var b = f.bar;
var z = f.baz;
here is b
referring to {some: "value"}
without {some: "value"}
magically "knowing" what f
stores a reference to it. This should be obvious.
The same is true for z
. It keeps the function without the function "knowing" that it is f
also referencing it. This should be just as obvious in theory.
The call z()
will give different results than the call f.baz()
, although the function called is the same. Only the context is different.
source to share
When a function is called its this variable dynamically allocates a value .
The function resolve
takes care of what the value is.
The third part of your code passes a function resolve
and then calls it without an object context Promise
.
This means it this
does not get the highlighted value Promise
that the function requires.
source to share