为什么不能将Promise.resolve作为函数调用?

tho*_*ter 5 javascript functional-programming promise ramda.js

有些东西让我和我的同事烦恼.考虑以下...

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]);
Run Code Online (Sandbox Code Playgroud)

正如您所期望的那样,输出1,2和3的棕褐色,以及解决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)
Run Code Online (Sandbox Code Playgroud)

Tom*_*lak 16

Promise.resolve没有上下文对象resolve函数.

您想用适当的上下文对象调用它.这可以做到

  • 通过在上下文对象上调用它,如v => Promise.resolve(v),或
  • 通过创建它的绑定版本,如 Promise.resolve.bind(Promise)

所以,这将工作:

compose(
  console.log,
  map(Promise.resolve.bind(Promise))
)([7,8,9]);
Run Code Online (Sandbox Code Playgroud)

请记住,Javascript没有类.功能没有所有者.对象可以在其属性中存储函数,但这并不意味着该函数由该对象拥有.

另一种方法是使用Function#call或显式设置上下文对象Function#apply:

function (v) {
    var resolve = Promise.resolve;
    return resolve.call(Promise, v);
}
Run Code Online (Sandbox Code Playgroud)

也许通过专注于除方法之外的其他方式来说明最好的说明:

function Foo() {
    this.bar = {some: "value"};
    this.baz = function () { return this.bar; };
}

var f = new Foo();
var b = f.bar;
var z = f.baz;
Run Code Online (Sandbox Code Playgroud)

这里b指的是{some: "value"}没有{some: "value"}神奇地"知道" f存储对它的引用.这应该是显而易见的.

同样如此z.它存储一个没有该功能的功能"知道" f也引用它.理论上,这应该是显而易见的.

即使被调用的函数是相同的,调用z()也会产生与调用不同的结果f.baz().只有背景不同.