2013-12-15 2 views
0

Ниже практически весь код для Node.js приложения, которое позволяет получить плейлист для художников, если вы запустите команду просто сопровождаемых художниками именифункция работает, которая явно не называется

simplay the Beatles 

С выходом в терминале я знаю, что код в методе ._flush (добавлен в прототип UrlsForNamesTransform) запускается, но он никогда явно не называется. UrlsForNamesTransform расширяет поток Transform в node.js, о котором я упоминаю, потому что видел его в другом коде до того, как работает функция без явного вызова (по крайней мере, того, что я вижу). Это что-то вроде Transform или того, что происходит, чтобы сделать код в ._flush run? Это GitHub репо для кода https://github.com/thlorenz/simplay

'use strict'; 

var urlschema = 'http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist={{artist}}&api_key={{apikey}}&format=json'; 

var hyperquest = require('hyperquest') 
    , table  = require('text-table') 
    , colors  = require('ansicolors') 
    , styles  = require('ansistyles') 

var stream = require('stream'); 
var util = require('util'); 

var Transform = stream.Transform; 

util.inherits(UrlsForNamesTransform, Transform); 

function UrlsForNamesTransform (opts) { 
    if (!(this instanceof UrlsForNamesTransform)) return new UrlsForNamesTransform(opts); 

    opts = opts || {}; 

    Transform.call(this, opts); 
    this._writableState.decodeStrings = false; 
    this.artist = opts.artist; 
    this.json = ''; 
} 

UrlsForNamesTransform.prototype._transform = function (chunk, encoding, cb) { 
    this.json += chunk.toString(); 
    cb(); 
}; 

UrlsForNamesTransform.prototype._flush = function (cb) { 
    var records = []; 
    try { 
    var o = JSON.parse(this.json); 
    var artists = o.similarartists.artist; 
    if (!Array.isArray(artists)) { 
     this.push('Sorry, no records for "' + this.artist + '" where found, please correct your spelling and/or try another artist.'); 
     return cb(); 
    } 

    artists.forEach(function (node) { 
     var youtubeurl = 'http://www.youtube.com/results?search_query={{artist}},playlist'.replace('{{artist}}', node.name); 
     var rdiourl = 'http://www.rdio.com/search/{{artist}}/artists/'.replace('{{artist}}', node.name); 
     var lastfmurl = 'http://www.last.fm/music/{{artist}}'.replace('{{artist}}', node.name); 
     var lastfmRadioUrl = 'http://www.last.fm/listen/artist/{{artist}}'.replace('{{artist}}', node.name); 
     var urls = [ 
      '' 
     , colors.white(' youtube:  ') + styles.underline(colors.brightBlue(encodeURI(youtubeurl))) 
     , colors.blue (' rdio:   ') + styles.underline(colors.brightBlue(encodeURI(rdiourl))) 
     , colors.brightRed (' last.fm:  ') + styles.underline(colors.brightBlue(encodeURI(lastfmurl))) 
     , colors.red (' last.fm radio: ') + styles.underline(colors.brightBlue(encodeURI(lastfmRadioUrl))) 
     , '' 
     , ''].join('\n'); 

     records.push([ '\n' + colors.brightYellow(node.name), colors.cyan(node.match), urls ]); 
    }) 
    this.push(table(records.reverse())); 
    cb(); 
    } catch (err) { 
    cb(err); 
    } 
} 


var go = module.exports = 

/** 
* Retrieves similar artists for the given artist from last.fm using the apikey. 
* Then it converts the information to display youtube.com, last.fm, rdio playlist/artist urls for each artist. 
* 
* @name simplay 
* @function 
* @param {String} artist the artist to find similar artists for 
* @param {String} apikey the api key to be used with last.fm 
* @return {ReadableStream} that will push the url information 
*/ 
function simplay(artist, apikey) { 
    if (!artist) throw new Error('Please provid the artist that you like to get similar artist links for'); 
    if (!apikey) throw new Error('Please set LASTFM_API env variable to your API key: http://www.last.fm/api/account/create'); 

    var url = urlschema 
    .replace('{{artist}}', artist) 
    .replace('{{apikey}}', apikey); 

    return hyperquest(url) 
    .on('error', console.error) 
    .pipe(new UrlsForNamesTransform({ artist: artist })) 
    .on('error', console.error) 
}; 

ответ

1

важная линия это одна:

util.inherits(UrlsForNamesTransform, Transform); 

Что это означает, что UrlsForNamesTransform является подклассом Transform. Существует очень хорошая документация по подклассу Transform, которая находится в on the node.js api site.

По существу, подкласс Transform должен реализовывать _transform и может реализовать _flush, но, как ожидается, никогда не будет вызывать ни одну из этих функций. Методы в Transform будут вызывать их на основе событий на входящем потоке.

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