所以我有一个节点应用程序,我正在解析一条推文并使用它来搜索歌曲,然后将歌曲存储到数据库中。我现在想将推文存储在数据库中。目前我将var从第一个函数一直传递到另外3个函数,然后存储推文。
我的问题是做这样的事情的更优雅/恰当的方法是什么。
感谢所有的教育和帮助。
我的代码目前有效,看起来像这样。
function start(Tuser, x) {
T.get('statuses/user_timeline', {screen_name: Tuser, count: x}, function (err, data) {
data.forEach(function (values) {
var tweet = values.text;
splitTweet(tweet);
});
});
}
function splitTweet(tweet) {
var arrayOfTweets = tweet.split("-");
var ArtistsStr = arrayOfTweets[0];
var SongStr = arrayOfTweets[1];
var SongNm = SongStr.split("playing");
var Song = SongNm[0].trim();
var ArtistsNm = ArtistsStr.replace(/\//g,"+");
var ArtistsNm = ArtistsNm.trim().replace(/ /g,"+");
res = /@/g.test(ArtistsNm);
if (res) {
console.log("Advertisement")
} else {
SoundSong(ArtistsNm, Song, tweet);
}
}
function SoundSong (A, S, tweet){
var SoundKey = "SHHH_ITS_A_SECRET";
S = S.replace(/ /g,"+");
A = A.replace(/ /g,"+");
var url = 'http://api.soundcloud.com/tracks.json?client_id=' + SoundKey + '&q=' + A + S +'&limit=1';
http.get(url, function(res){
var data = '';
res.on('data', function (chunk){
data += chunk;
});
res.on('end', function(){
var obj = JSON.parse(data);
if(typeof obj.errors != 'undefined'){
console.log('ERROR: ' + obj.errors[0].error_message);
}else{
ParseSoundSong(obj, tweet)
}
});
});
}
function ParseSoundSong (obj, tweet){
if(typeof obj[0] != 'undefined'){
var id = obj[0].id;
var SongName = obj[0].title;
var uri = obj[0].uri;
var SongDate = moment().format('l h:mm:ss a');
if(typeof uri === 'undefined'){
uri = 'null';
}
var Songs = myFirebaseRef.child(id);
Songs.set({
uri: uri,
SongName: SongName,
Date: SongDate,
Tweet: tweet
});
}else{
console.log(obj);
}
}
答案 0 :(得分:2)
导致您必须将tweet
从一个函数传递到下一个函数的原因是您正在执行嵌套函数调用,您调用A()
从内部调用B()
它从里面调用C()
,从里面调用D()
,最终需要推文数据。相反,如果您重新构建代码,以便A()
,B()
和C()
是执行操作并返回结果的函数,那么您可以在概念上这样做:< / p>
var tweet = ...
var someResult = A(...);
var nextResult = B(...);
var anotherResult = C(...);
D(tweet, ...);
或者,因为您的某个函数是异步的,所以您可以使用回调来执行此操作:
var tweet = ...
var someResult = A(..., function(results) {
var nextResult = B(...);
var anotherResult = C(...);
D(tweet, ...);
});
这样做的好处是,您的函数A()
,B()
和C()
会变成更有用的代码片段,因为它们只执行特定的操作并返回结果而不是硬连线进入一系列多次通话。我将使用您的代码处理一个特定的示例。
以下是关于如何构建结构的想法(显然未经测试):
function start(Tuser, x) {
T.get('statuses/user_timeline', {screen_name: Tuser, count: x}, function (err, data) {
data.forEach(function (values) {
var tweet = values.text;
var tweetData = new ParsedTweet(tweet);
if (tweetData.isAdvertisement) return;
getSoundInfo(tweetData.songNm, tweetData.artistsNm, function(err, data) {
if (err) return;
var soundInfo = parseSoundSong(data);
if (!soundInfo) return;
var songs = myFirebaseRef.child(soundInfo.id);
songs.set({
uri: soundInfo.uri,
SongName: soundInfo.SongName,
Date: soundInfo.Date,
Tweet: tweet
});
});
});
});
}
function ParsedTweet(tweet) {
var arrayOfTweets = tweet.split("-");
this.tweet = tweet;
this.artistsStr = arrayOfTweets[0];
this.songStr = arrayOfTweets[1];
this.songNm = this.songStr.split("playing");
this.song = this.songNm[0].trim();
this.artistsNm = this.artistsStr.replace(/\//g,"+").trim().replace(/ /g,"+");
this.isAdvertisement = /@/g.test(this.artistsNm);
}
function getSoundInfo(songName, artistName, fn) {
var soundKey = "SHHH_ITS_A_SECRET";
var song = songName.replace(/ /g,"+");
var artist = artistName.replace(/ /g,"+");
var url = 'http://api.soundcloud.com/tracks.json?client_id=' + soundKey + '&q=' + artist + song +'&limit=1';
http.get(url, function(res){
var data = '';
res.on('data', function (chunk){
data += chunk;
});
res.on('end', function(){
var obj = JSON.parse(data);
if(typeof obj.errors != 'undefined'){
console.log('ERROR: ' + obj.errors[0].error_message);
fn(obj.errors);
} else{
fn(0, obj);
}
});
res.on('error', function(err) {
fn(err);
});
});
}
function parseSoundSong(obj) {
if(typeof obj[0] != 'undefined'){
var result = {};
result.id = obj[0].id;
result.SongName = obj[0].title;
result.uri = obj[0].uri;
result.Date = moment().format('l h:mm:ss a');
if(typeof result.uri === 'undefined'){
result.uri = 'null';
}
return result;
} else {
return null;
}
}