无法将 lodash partial 应用于使用 bluebird promisifyAll 创建的函数
Can't apply lodash partial to function created with bluebird promisifyAll
下面的代码采用对象 lib
中的所有方法并承诺它们。然后我可以使用回调样式函数作为承诺,这很有效。然后我用_.partial
提供函数和参数,这个returns一个函数。当我调用该函数时,它会抛出错误而不是包装函数。我有一大堆测试 here 表明这种行为只发生在使用 promisifyAll
生成的函数中。这里有什么问题,如何解决?
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
正在投掷
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
而这工作得很好。
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"
})
promisifyAll
确实创建了期望在原始实例上调用的方法(因为它确实调用了原始 .dummy
方法),但 partial
不绑定您传递的函数in,所以你得到一个 this
错误。您可以使用 readFile.call(lib)
或 _.partial(lib.dummyAsync.bind(lib), …)
或仅使用 lib.dummyAsync.bind(lib, …)
.
正在复制答案from the issue tracker:
问题是 _.partial
没有维护 promisifyAll
时所需的 this
值。您可以使用 promisify
代替,也可以使用 _.bind
这是合适的 lodash 方法。
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);
});
下面的代码采用对象 lib
中的所有方法并承诺它们。然后我可以使用回调样式函数作为承诺,这很有效。然后我用_.partial
提供函数和参数,这个returns一个函数。当我调用该函数时,它会抛出错误而不是包装函数。我有一大堆测试 here 表明这种行为只发生在使用 promisifyAll
生成的函数中。这里有什么问题,如何解决?
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
正在投掷
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
而这工作得很好。
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"
})
promisifyAll
确实创建了期望在原始实例上调用的方法(因为它确实调用了原始 .dummy
方法),但 partial
不绑定您传递的函数in,所以你得到一个 this
错误。您可以使用 readFile.call(lib)
或 _.partial(lib.dummyAsync.bind(lib), …)
或仅使用 lib.dummyAsync.bind(lib, …)
.
正在复制答案from the issue tracker:
问题是 _.partial
没有维护 promisifyAll
时所需的 this
值。您可以使用 promisify
代替,也可以使用 _.bind
这是合适的 lodash 方法。
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);
});