2017-11-24 5 views
0

Ich hole PlaylistId von Youtube API.Variable undefined außerhalb Youtube Suche API-Funktion

Es gibt korrekte Ausgabe, wenn Konsolenausgabe innerhalb der Youtube-Suchfunktion.

Es gibt undefined außerhalb youtube Suche API-Funktion.

var playlistId; 
async function suggestTrack(genre) { 

    youtube.search.list({ 
     auth: config.youtube.key, 
     part: 'id,snippet', 
     q: genre 
    }, function (err, data) { 
     if (err) { 
     console.error('Error: ' + err); 
     } 
     if (data) { 
     console.log(data.items[0].id.playlistId); //getting the id 
     playlistId = data.items[0].id.playlistId; 

     } 
     //process.exit(); 
    }); 

    console.log(playlistId);// undefined 

const tracks = await youtube_api.getPlaylistTracks(playlistId); 
return tracks[Math.floor(tracks.length * Math.random())]; 

} 

Antwort

2

Der API-Aufruf ist asynchron. Und Sie drucken den Wert playlistId, bevor die Antwort der API sogar zurückkommt. Sie müssen auf die Antwort warten. Und da Sie async verwenden, wickeln Sie den API-Anruf in eine Promise und verwenden Sie await. Um promisify die search.list Methode haben Sie eine Menge von Optionen, oder Sie können es selbst tun, wie unten

function search(key, part, genre) { 
    return new Promise((resolve, reject) => { 
    youtube.search.list({ 
     auth: key, 
     part: part, 
     q: genre 
    }, function (err, data) { 
     if (err) { 
     reject(err); 
     return; 
     } 
     // use better check for playlistId here 
     resolve(data ? data.items[0].id.playlistId : null); 
    }) 
    }); 
} 

// then use it here 
async function suggestTrack(genre) { 
    const playlistId = await search(config.youtube.key, 'id,snippet', genre);  
    const tracks = await youtube_api.getPlaylistTracks(playlistId); 
    return tracks[Math.floor(tracks.length * Math.random())]; 
} 
2

youtube.search.list asynchron ist. Sie versuchen, auf playlistId zuzugreifen, da es Teil eines synchronen Prozesses war.

Sie können die youtube.search.list innerhalb einer Promise umhüllen, um die Verwendung zu vereinfachen.


OLD WAY

function wrappedSearch() { 
    return new Promise((resolve, reject) => { 
    youtube.search.list({ 
     auth: config.youtube.key, 
     part: 'id,snippet', 
     q: genre 
    }, (err, data) => { 
     if (err) { 
     console.error('Error: ' + err); 

     return reject(err); 
     } 

     return resolve((data && data.items[0].id.playlistId) || false); 
    }); 
    }); 
} 

async function suggestTrack(genre) { 
    const playlistId = await wrappedSearch(); 

    // Here playlistId is either the playlistId, either false 

    console.log(playlistId); 

    const tracks = await youtube_api.getPlaylistTracks(playlistId); 

    return tracks[Math.floor(tracks.length * Math.random())]; 
} 

NEW WAY

erhältlich Knoten v8 doc tutorial

const { 
    promisify, 
} = require('util'); 

const youtubeSearchAsync = promisify(youtube.search.list); 

async function suggestTrack(genre) { 
    const data = await youtubeSearchAsync({ 
     auth: config.youtube.key, 
     part: 'id,snippet', 
     q: genre 
    }); 

    const playlistId = (data && data.items[0].id.playlistId) || false; 

    console.log(playlistId); 

    const tracks = await youtube_api.getPlaylistTracks(playlistId); 

    return tracks[Math.floor(tracks.length * Math.random())]; 
} 
+0

neuer Weg funktioniert nicht ... sagen Daten nicht definiert –

+0

@YaShChaudhary ich habe einen Fehler bei der Benennung der var gemacht. Ich habe es gerade geändert –