为什么 Promise.resolve 不能作为函数调用?
Why can't Promise.resolve be called as a function?
困扰我和我同事的事情。考虑以下...
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]);
如您所料,输出 1、2 和 3 的 tan 以及解决 3、4 和 5 的承诺。但我的问题是......为什么第三个中断?为什么 Promise.resolve 的行为方式与其他函数不同?
[ 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)
当函数被调用时 this variable is dynamically allocated a value。
resolve
函数关心那个值是什么。
您的代码的第三部分传递 resolve
函数,然后在没有 Promise
对象的上下文的情况下调用它。
这意味着 this
没有分配函数需要的 Promise
的值。
Promise.resolve
需要用 this
作为 Promise 构造函数(或子类)调用。
resolve = Promise.resolve;
resolve(null); // Error
resolve.call({}); // Error: Object is not a constructor
因此更改此行:
map(Promise.resolve)
至:
map(Promise.resolve.bind(Promise))
Promise.resolve
引用 resolve
函数 没有上下文对象 .
您想用适当的上下文对象调用它。这可以做到
- 通过在该上下文对象上调用它,如
v => Promise.resolve(v)
或
- 通过创建它的绑定版本,如
Promise.resolve.bind(Promise)
所以,这会起作用:
compose(
console.log,
map(Promise.resolve.bind(Promise))
)([7,8,9]);
记住 Javascript 没有 类。函数没有所有者。对象可以在其属性中存储函数,但这并不意味着该函数属于该对象。
另一种方法是显式设置上下文对象,使用 Function#call
或 Function#apply
:
function (v) {
var resolve = Promise.resolve;
return resolve.call(Promise, v);
}
也许最好通过关注方法以外的东西来说明:
function Foo() {
this.bar = {some: "value"};
this.baz = function () { return this.bar; };
}
var f = new Foo();
var b = f.bar;
var z = f.baz;
这里 b
引用 {some: "value"}
而 {some: "value"}
神奇地 "knowing" f
存储了对它的引用。这应该是显而易见的。
z
也是如此。它存储一个没有函数 "knowing" 的函数,f
也引用它。从理论上讲,这应该同样明显。
调用 z()
将产生与调用 f.baz()
不同的结果,即使调用的函数是同一个函数。只是语境不同。
困扰我和我同事的事情。考虑以下...
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]);
如您所料,输出 1、2 和 3 的 tan 以及解决 3、4 和 5 的承诺。但我的问题是......为什么第三个中断?为什么 Promise.resolve 的行为方式与其他函数不同?
[ 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)
当函数被调用时 this variable is dynamically allocated a value。
resolve
函数关心那个值是什么。
您的代码的第三部分传递 resolve
函数,然后在没有 Promise
对象的上下文的情况下调用它。
这意味着 this
没有分配函数需要的 Promise
的值。
Promise.resolve
需要用 this
作为 Promise 构造函数(或子类)调用。
resolve = Promise.resolve;
resolve(null); // Error
resolve.call({}); // Error: Object is not a constructor
因此更改此行:
map(Promise.resolve)
至:
map(Promise.resolve.bind(Promise))
Promise.resolve
引用 resolve
函数 没有上下文对象 .
您想用适当的上下文对象调用它。这可以做到
- 通过在该上下文对象上调用它,如
v => Promise.resolve(v)
或 - 通过创建它的绑定版本,如
Promise.resolve.bind(Promise)
所以,这会起作用:
compose(
console.log,
map(Promise.resolve.bind(Promise))
)([7,8,9]);
记住 Javascript 没有 类。函数没有所有者。对象可以在其属性中存储函数,但这并不意味着该函数属于该对象。
另一种方法是显式设置上下文对象,使用 Function#call
或 Function#apply
:
function (v) {
var resolve = Promise.resolve;
return resolve.call(Promise, v);
}
也许最好通过关注方法以外的东西来说明:
function Foo() {
this.bar = {some: "value"};
this.baz = function () { return this.bar; };
}
var f = new Foo();
var b = f.bar;
var z = f.baz;
这里 b
引用 {some: "value"}
而 {some: "value"}
神奇地 "knowing" f
存储了对它的引用。这应该是显而易见的。
z
也是如此。它存储一个没有函数 "knowing" 的函数,f
也引用它。从理论上讲,这应该同样明显。
调用 z()
将产生与调用 f.baz()
不同的结果,即使调用的函数是同一个函数。只是语境不同。