我正在尝试将一些代码包装到节点模块中,但是发生了一个问题。
我的测试代码:
var Twitter_Client = require('./src/twitter-client');
var twitterClient = new Twitter_Client({
consumer_key : '',
consumer_secret : '',
access_token_key : '',
access_token_secret : ''
});
twitterClient.tweet([{path: 'some_path', type: 'image/jpg'}],'test');
我的模块看起来像这样:
var Twitter = require('twitter');
var fs = require('fs');
var Promise = require("bluebird");
function Twitter_Client(opts){
if (!(this instanceof Twitter_Client))
return new Twitter_Client(opts);
this._client = new Twitter(opts);
this._tray = [];
}
Twitter_Client.prototype.makePost = (endpoint, params)=>{
...
};
Twitter_Client.prototype.uploadMedia = (path, type)=>{
...
};
Twitter_Client.prototype.tweet = (medias, status)=>{
var that = this;
console.log(this instanceof Twitter_Client);
return (()=>{
if (!Array.isArray(medias) || medias.length == 0) {
return Promise.resolve([]);
} else {
return Promise.resolve(medias).map((media) => {
return that.uploadMedia(media.path, media.type);
});
}
})().then((mediaids) => {
return new Promise((resolve,reject)=>{
that._client.post('statuses/update', {
status : status,
media_ids : mediaids.join(',')
}, function (error, tweet, response) {
if (error) {
reject(error);
}
resolve(tweet);
});
});
});
};
module.exports = Twitter_Client;
这个模块有三个功能,但是如果我发布所有功能就会太长,所以我只展示其中一个被测试代码调用的功能。 当我运行上面的代码时,它给了我:
false
Unhandled rejection TypeError: that.uploadMedia is not a function
似乎我没有从这个'中获得正确的对象。 我已经阅读了许多类似的问题,似乎我正在以正确的方式创建一个对象并从对象而不是实例调用该函数。 我的代码出了什么问题?
答案 0 :(得分:2)
问题在于您将方法定义为胖箭头功能。由于胖箭头函数的工作方式,这意味着this
值来自模块中的本地上下文,而不是来自您调用方法的对象。所以,改变这个:
Twitter_Client.prototype.tweet = (medias, status)=>{
到此:
Twitter_Client.prototype.tweet = function(medias, status){
并且,也改变所有其他方法。这是一个永远不应该使用胖箭头函数的地方,因为它们明确地破坏了对象方法的this
值。
仅供参考,因为看起来您正在使用Bluebird承诺,您可以更改此信息:
return Promise.resolve(medias).map((media) => {
return that.uploadMedia(media.path, media.type);
});
到此:
return Promise.map(medias, (media) => {
return that.uploadMedia(media.path, media.type);
});