2016-04-14 15 views
0

Ich mache Node.js Anwendung mit Express.js. Ich habe eine Seite, die einige Daten von anderer Seite rendert. also benutze ich mit Cheerio.js und es ist kein Problem, aber das Problem ist, ich weiß nicht, wie kann ich rendern, wenn die Verschrottung abgeschlossen ist. Ich habe einen Code wie unten gemacht, bitte.Node.js Res.Render, wenn Aufgabe abgeschlossen

var urls = [ 'http://a.com/fruits', 'http://a.com/cars', 'http://a.com/toys' ] 

function getData(){ 

// get html and parse, return some data. 
    ...  
} 

var data_set = ''; 

for (var i=0; i< urls.length ; i++){ 
    data_set += getData(urls[i]); 
} 

// When get all data, render <------ How can I catch when? 
res.render('some_page', { data : data_set }); 

Thought einige Möglichkeiten, es zu tun,

# 1 - Rendern wenni == urls.length

for (var i=0; i< urls.length ; i++){ 
    data_set += getData(urls[i]); 
    if(i == urls.length){ 
     res.render(....); 
    } 
} 

// Result : 
// The data has not been scrapped, so the page wouldn't display data fully. 

# 2 - Rückruf mit getData()

function getData(callback){ 

// get html and parse, return some data. 
    ... 
// when complete, callback();   
} 

var someHelper = 0; 
getData(function(){ someHelper ++ ;}); 

if (someHelper == 3){ 
    res.render(...); 
} 

// If someHeper is not 3, the page would not rendered. 
// And `if statement` executed before someHelper == 3 at times ==> infinite page loading (error) 

Wie kann ich han dle das? Sollte ich Verwendung finden Promise? ... Bitte helfen Sie mir mit einigen Punkten. können Sie mit tun könnte

function getData(urlString) { 
    return new Promise(function (res, rej) { 
     //fetch and resolve promise with data from urlString 
    }); 
} 

var data_set = ''; 
var promises = []; 
for (var i=0; i< urls.length ; i++){ 
    promises.push(function() { 
     return getData(urls[i]).then(function (data) { 
      data_set += data; 
     }); 
    }); 
} 

Promise.all(promises).then(function() { 
    res.render('some_page', { data : data_set }); 
}); 
+0

Ich schlage 'Promise' für diese – kiro112

+0

@ kiro112 Ich weiß nicht, was ist kompilierte Vorlage ... es nur ein paar Zahlen. – Juntae

Antwort

2

sollten Sie entweder Versprechen oder async.js Bibliothek an Ihnen wirklich verwenden ...

hier, wie Sie es verspricht. Sie können die Funktion getData einzeln aufrufen und den Inhalt in jeder Callback-Funktion an data_set anhängen.

var urls = [ 'http://a.com/fruits', 'http://a.com/cars', 'http://a.com/toys' ], data_set = ''; 

function getData(url, cb){ 

    // get html and parse, return some data. 
     ... 
    // call cb when downloaded contents 
    cb(content); 

} 

getData(urls[0], function (content) { 

    data_set += content; 
    getData(urls[1], function (content) { 

     data_set += content; 
     getData(urls[2], function (content) { 
      data_set += content; 
      res.render('some_page', { data : data_set }); 
     } 

    } 

}); 

Rückruf Hölle zu vermeiden, können Sie auch Modul wie "async", "q", "Versprechen" verwenden.

+0

Danke. aber 'var verspricht = []; und Promise.all (Versprechungen) .then ... 'Die then() - Funktion, die zuvor ausgeführt wurde, verspricht das Array gefüllt. – Juntae

+0

so ist das data_set leer. Es ist so schwierig .... – Juntae

+0

nein ist es nicht, jede "getData" -Funktion wird während des "Promise.all" -Aufrufs gelöst und später in "then" haben Sie alle Ihre abgeschlossenen Ergebnisse –

0

Nested Rückrufe helfen

Verwandte Themen