callback风格的原型方法promise化,this为undefined - CNode技术社区

callback风格的原型方法promise化,this为undefined
发布于 11 年前 作者 zhaomaoxin 7004 次浏览 最后一次编辑是 9 年前 来自 问答

在使用Q模块重构之前使用Async编写的代码时,在使用Q.denodeify()方法进行promise化并执行的时候提示方法内部的this为undefined, 并提示undefined 没有xxx方法。有没有遇到过类似的问题,或者是我用得不对,请大家支支招。

11 回复

这还要代码?? 好吧!

 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

回到顶部

AltStyle によって変換されたページ (->オリジナル) /