2014-12-26 5 views
0
var yModule = require('youtube-node'), 
    nodeYoutube = new yModule(); 

nodeYoutube.setKey("key"); 

module.exports.getVideoLength = function (vData){ 
    youTube.getById(vData, function (result) { 
     return convertTime(result['items'][0]['contentDetails']['duration']); 
    }) 
}; 

var convertTime = function (time){ 
    var reptms = /(?:(\d+)DT)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/; 
    var days = "00", hours = "00", minutes = "00", seconds = "00", formattedTime; 


    //if (reptms.test(time)) { 
     var matches = reptms.exec(time); 
     console.log(matches); 
     if (matches[1]) days = String(matches[1]); 
     if (matches[2]) hours = String(matches[2]); 
     if (matches[3]) minutes = String(matches[3]); 
     if (matches[4]) seconds = String(matches[4]); 
     formattedTime = "[" + days + ":" + hours + ":" + minutes + ":" + seconds + "]"; 
     return formattedTime; 
    //} 
}; 

Я пытаюсь понять обратные вызовы даже после прочтения нескольких вещей об этом. nodeJs callbacks simple example это немного помогло, но я все еще не понимаю, как это работает. Я потратил последний час, пытаясь понять, как писать это, используя обратные вызовы.Нужно ли использовать обратные вызовы?

Этот модуль вызывается этим: функция

ytRetrieve.getVideoLength(youtube_parser(text)) 

youtube_parser в:

function youtube_parser(url){ 
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/; 
    var match = url.match(regExp); 
    //console.log(match); 
    if (match&&match[7]){ 
     return match[7].split(" ")[0]; 
    } 
} 
+0

Что 'bot'? Вы создали это или это какой-то другой модуль? –

+0

@ExplosionPills - это модуль 'irc' – ECMAScript

+0

Это весело. Имя пользователя "ECMAScript", если требуется обратный вызов :) Короткий ответ: да, всегда, особенно в узле. Вот отличный [ресурс по обратным вызовам] (http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/), который поможет вам обвести вокруг себя голову. Ура! –

ответ

0

Вот решение, с которым я пришел. Есть ли что-то, что я могу сделать, чтобы улучшить этот код?

Благодарим за помощь.

Main.js

var ytempRetrieve = require('./youtube'), ytRetrieve = new ytempRetrieve(); 

var ytRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?/; 


bot.addListener('message', function (from, to, text, message) { 
    if (text.match(ytRegex)) { 
     console.log(text); 
     youtube_parser(text, to, ytRetrieve.getVideoLength) 
    } 
}); 

function youtube_parser(url, to, callback) { 
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/; 
    var match = url.match(regExp); 
    //console.log(match); 
    if (match && match[7]) { 
     callback(match[7].split(" ")[0], function (res) { 
      setTimeout(function() { 
       bot.say(to, match[7].split(" ")[0] + " is " + res + " long.") 
      }, 1500) 
     }); 
    } 
} 

youtube.js

var yModule = require('youtube-node'), 
    nodeYoutube = new yModule(), 
    apiKey = require('./config'); 


    var youtube = function() { 
    var self = this; 

    self.time = null; 

    self.setAPIKey = function (key) { 
     nodeYoutube.setKey(key); 
    }; 

    apiKey.getAPIKey(self.setAPIKey); 

    self.getVideoLength = function (vData, callback) { 
     nodeYoutube.getById(vData, function (result) { 
      callback(self.convertTime(result['items'][0]['contentDetails']['duration'])); 
     }) 
    }; 

    self.convertTime = function (time) { 
     var reptms = /(?:(\d+)DT)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/; 
     var days = 0, hours = 0, minutes = 0, seconds = 0, formattedTime; 

     //if (reptms.test(time)) { 
     var matches = reptms.exec(time); 
     console.log(matches); 
     if (matches[1]) days = Number(matches[1]); 
     if (matches[2]) hours = Number(matches[2]); 
     hours += days * 24; 
     if (hours.toString().length === 1) { 
      hours = "0" + hours 
     } 
     if (matches[3]) minutes = String(matches[3]); 
     if (minutes.toString().length === 1) { 
      minutes = "0" + minutes 
     } 
     if (matches[4]) seconds = String(matches[4]); 
     if (seconds.toString().length === 1) { 
      seconds = "0" + seconds 
     } 
     formattedTime = "[" + hours + ":" + minutes + ":" + seconds - 1 + "]"; 
     return (formattedTime); 
     //} 
    }; 

}; 

module.exports = youtube; 
0

Вы должны использовать обратные вызовы. Проблема с вашим кодом youtube_parser( заключается в том, что вы являетесь , вызывая функцию. Обратный вызов - это функция, которая передается как аргумент, который будет вызываться позже. Если вы вызываете функцию, возвращается строка. getVideoLength ожидает функцию как аргумент, а не строку.

Вместо этого используйте getVideoLength(youtube_parser). Это фактически проходит в самой функции youtube_parser, которая будет называться позже (то есть когда getVideoLength завершает). Однако аргументы youtube_parser, возможно, должны быть (error, url).

+0

«Обратный вызов - это функция, которая передается как аргумент, который будет вызываться позже». Я этого не понимаю. И что мне делать с параметром ошибки? Я пытаюсь вызвать getVideoLength после того, как youtube_parser вернет значение. – ECMAScript

+0

Обновлено с решением, которое я попробовал, что дает мне undefined не является функцией ошибки – ECMAScript

+0

@ECMAScript, что вы не понимаете? Вы можете передать строку, целое число или логическое значение в качестве аргумента. Почему не функция? –

Смежные вопросы