簡體   English   中英

為什么不能將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的棕褐色,以及解決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)

Promise.resolve是指沒有上下文對象resolve函數。

您想用適當的上下文對象調用它。 這可以做到

  • 通過在該上下文對象上調用它,如在v => Promise.resolve(v) ,或
  • 通過創建它的綁定版本,如Promise.resolve.bind(Promise)

所以,這將工作:

compose(
  console.log,
  map(Promise.resolve.bind(Promise))
)([7,8,9]);

請記住,Javascript沒有類。 功能沒有所有者。 對象可以在其屬性中存儲函數,但這並不意味着該函數由該對象擁有。

另一種方法是使用Function#callFunction#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"}神奇地“知道” f存儲對它的引用。 這應該是顯而易見的。

z也是如此。 它存儲一個沒有該功能的函數“知道” f也引用它。 理論上,這應該是顯而易見的。

調用z()將產生與調用f.baz()不同的結果,即使被調用的函數是相同的。 只有背景不同。

調用函數時, 此變量會動態分配一個值

resolve函數關心該值是什么。

代碼的第三部分傳遞resolve函數,然后在沒有Promise對象的上下文的情況下調用它。

這意味着this不會分配函數所需的Promise值。

需要調用Promise.resolvethis是一個Promise構造函數(或子類)。

resolve = Promise.resolve;
resolve(null); // Error
resolve.call({}); // Error: Object is not a constructor

所以改變這一行:

map(Promise.resolve)

至:

map(Promise.resolve.bind(Promise))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM