Can't apply lodash partial to function created with bluebird promisifyAll

孤人 提交于 2019-12-13 04:42:17

问题


The below code takes a all the methods in object lib and promisify's them. Then I can use the callback style function as a promise, which works. Then I use _.partial provide the function and arguments, this returns a function. When I call that function it throws an error instead of wrapping the function. I have a whole bunch of tests here that show that this behavior only happens to functions generated with promisifyAll. What's the problem here and how can it be fixed?

var Promise = require("bluebird")
var _ = require("lodash")

var lib = {}

lib.dummy = function(path, encoding, cb){
  return cb(null, "file content here")
}

Promise.promisifyAll(lib)

lib.dummyAsync("path/hello.txt", "utf8").then(function(text){
  console.log(text) // => "file content here"
})

var readFile = _.partial(lib.dummyAsync, "path/hello.txt", "utf8")

readFile() // throws error

It's throwing

Unhandled rejection TypeError: Cannot read property 'apply' of undefined
    at tryCatcher (/Users/thomas/Desktop/project/node_modules/bluebird/js/main/util.js:26:22)
    at ret (eval at <anonymous> (/Users/thomas/Desktop/project/node_modules/bluebird/js/main/promisify.js:163:12), <anonymous>:11:39)
    at wrapper (/Users/thomas/Desktop/project/node_modules/lodash/index.js:3592:19)
    at Object.<anonymous> (/Users/thomas/Desktop/project/issue.js:18:1)
    at Module._compile (module.js:426:26)
    at Object.Module._extensions..js (module.js:444:10)
    at Module.load (module.js:351:32)
    at Function.Module._load (module.js:306:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:117:18)
    at node.js:946:3

Whereas this works perfectly fine.

var dummyPromise = function(path, encoding){
  return Promise.resolve("file content here")
}

var readFile = _.partial(dummyPromise, "path/hello.txt", "utf8")

readFile().then(function(text){
  console.log(text) // => "file content here"
})

回答1:


Copying answer from the issue tracker:

The problem is _.partial does not maintain the this value which is required when you promisifyAll. You can either use promisify instead or you can use _.bind which is the appropriate lodash method.

var o = {};
o.dummy = function(path, encoding, cb){
  return cb(null, "file content here " + path + " " +encoding);
}

Promise.promisifyAll(o);

o.dummyAsync("a","b").then(function(data){
   console.log("HI", data); 
});

// and not `_.partial`
var part = _.bind(o.dummyAsync, o, "a1", "b2");
part().then(function(data){
   console.log("Hi2", data); 
});

http://jsfiddle.net/hczmb2kx/




回答2:


promisifyAll does create methods that expect to be called on the original instance (as it does invoke the original .dummy method), but partial does not bind the functions you pass in, so you are getting a this error. You can use either readFile.call(lib) or _.partial(lib.dummyAsync.bind(lib), …) or just lib.dummyAsync.bind(lib, …).



来源:https://stackoverflow.com/questions/31639639/cant-apply-lodash-partial-to-function-created-with-bluebird-promisifyall

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!