javascript - 在 JS 中通过函数传递变量的最佳方法

标签 javascript node.js

所以我有一个 Node 应用程序,我可以在其中解析推文并使用它来搜索歌曲,然后将歌曲存储到数据库中。我现在想将推文存储在数据库中。目前,我将 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);
    }
}

最佳答案

导致您必须将 tweet 从一个函数传递到下一个函数的原因是您正在执行嵌套函数调用,其中调用 A()从内部调用 B() 从内部调用 C() 从内部调用 D() 最终需要推文数据。相反,如果您重构代码,使 A()B()C() 成为执行操作的函数并返回他们的结果,那么你可以在概念上这样做:

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;
    }
}

关于javascript - 在 JS 中通过函数传递变量的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27462945/

相关文章:

javascript - 删除字符串中的重复字符

javascript - 为什么 Javascript 中不保存 cookie?

javascript - import {} from '.' 的作用是什么?

javascript - AngularJS。使用不同的数据初始化 Controller

node.js - 如何让多个项目共享 node_modules 目录?

javascript - 如何让 javascript 捕获来自 Node 的信号并在之后立即提示一个窗口?

javascript - NodeJs Testrunner 在设置 Express 服务器时卡住/停止

javascript - 是否可以在 Typescript 中动态定义常量?

node.js - 如何在 twilio 函数内调用第 3 方 HTTP API?

javascript - TSLint 在本地抛出 'error TS2459: Module '“@azure/core-tracing "' declares ' Span,但未导出。”和其他错误