在使用Q模块重构之前使用Async编写的代码时,在使用Q.denodeify()方法进行promise化并执行的时候提示方法内部的this为undefined, 并提示undefined 没有xxx方法。有没有遇到过类似的问题,或者是我用得不对,请大家支支招。
这还要代码?? 好吧!
var client = oss.ossClient; var putObject = Q.denodeify(myPutObject); function uploadOss(file) { var stream = fs.createReadStream(file.filePath); var option = { bucket: bucket, object: file.objectPath, srcFile: stream, contentType:file.contentType, contentLength: file.length }; return putObject(option).then(function(result){ fs.unlinkSync(file.filePath); req.oss = ossPath; console.log(result.statusCode); return next(null); }, function(error){ fs.unlinkSync(file.filePath); return next(error); }); } Q.all(fileList.map(uploadOss)).done();
因为oss内部调用了自身的request方法,这段代码运行的时候报错,undefined没有request方法。
自己把oss里面的putObject代码拿出来,显示的传了一个obj进行,这样就可以了,代码如下所示,但是这不合理呀,咋还要改别人的模块呢!
//自己封装的,代码来源oss-client/putObject
function myPutObject(obj, option, callback) { callback = callback || noop; var self = obj; if (typeof option.srcFile === 'string') { // upload by file path fs.stat(option.srcFile, function(err, state) { if (err) { return callback(err); } option.contentLength = state.size; //todo: add option.md5 = ... self.request('PUT', null, option, callback); }); } else { // upload by buffer or stream self.request('PUT', null, option, callback); } }
//新的调用方法
var client = oss.ossClient; var putObject = Q.denodeify(myPutObject); function uploadOss(file) { var stream = fs.createReadStream(file.filePath); var option = { bucket: bucket, object: file.objectPath, srcFile: stream, contentType:file.contentType, contentLength: file.length }; return putObject(client, option).then(function(result){ fs.unlinkSync(file.filePath); req.oss = ossPath; console.log(result.statusCode); return next(null); }, function(error){ fs.unlinkSync(file.filePath); return next(error); }); } Q.all(fileList.map(uploadOss)).done();
bluebird
oss.putObjectAsync = Promise.promisify(oss.putObject);
同理denodeify
@magicdawn 同理,存在我说的这个问题吗?
@zhaomaoxin
Q不了解,我的意思是把 denodeify得到的async方法赋给那个obj
好的,我先用bluebird写写看。
@magicdawn 试了一下,同样的问题,你们就没有遇到过这样的问题吗?就是比如oss这个模块里面的方法putObject方法内部调用了this.request()这样的方法的时候报错,报undefined没有方法request,或者this被当作了全局对象global,这样报Object没有putObject这个方法就很正常了,就是promise化的时候对象转移了。
可以直接绑定到原来的对象上
@left node 有可以直接使用的方法吗?fcall, fncall之类的吗?刚接触这个东西,玩不溜
q文档 https://github.com/kriskowal/q#adapting-node
var putObjectAsync = Q.nbind(oss.putObject,oss)
好像不是q的问题。应该是javascript的执行上下文搞混了。
function Test() { this.a = 1; } Test.prototype.get = function() { console.log(this.a); }; var T = new Test(); T.get(); var newTest = T.get; newTest(); var newTestB = T.get.bind(T); newTestB();
给putObject bind 上oss
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
这还要代码?? 好吧!
因为oss内部调用了自身的request方法,这段代码运行的时候报错,undefined没有request方法。
自己把oss里面的putObject代码拿出来,显示的传了一个obj进行,这样就可以了,代码如下所示,但是这不合理呀,咋还要改别人的模块呢!
//自己封装的,代码来源oss-client/putObject
//新的调用方法
bluebird
同理denodeify
@magicdawn 同理,存在我说的这个问题吗?
@zhaomaoxin
Q不了解,我的意思是把 denodeify得到的async方法赋给那个obj
好的,我先用bluebird写写看。
@magicdawn 试了一下,同样的问题,你们就没有遇到过这样的问题吗?就是比如oss这个模块里面的方法putObject方法内部调用了this.request()这样的方法的时候报错,报undefined没有方法request,或者this被当作了全局对象global,这样报Object没有putObject这个方法就很正常了,就是promise化的时候对象转移了。
可以直接绑定到原来的对象上
@left node 有可以直接使用的方法吗?fcall, fncall之类的吗?刚接触这个东西,玩不溜
q文档 https://github.com/kriskowal/q#adapting-node
好像不是q的问题。应该是javascript的执行上下文搞混了。
给putObject bind 上oss