node.js - Apel de revenire (callback) în JavaScript vs return
Am o funcție JavaScript (Node) pentru a prelua conținutul unei pagini web și a-l procesa cu un callback:
'using strict';
var http = require('http');
function download(url, callback) {
http.get(url, function(res) {
var content = '';
res.on('data', function (chunk) {
content += chunk;
});
res.on('end', function() {
callback(content);
});
}).on('error', function() {
callback(null);
});
}
Ceea ce nu înțeleg este de ce nu pot pur și simplu să returnez rezultatul la 'end'. În mod clar, atunci când evenimentul 'end' este emis, variabila 'content' conține un șir cu conținutul unei pagini web, altfel nu ar putea fi transmisă funcției callback, așa că de ce nu pot să o returnez pur și simplu astfel:
function download2(url) {
http.get(url, function(res) {
var content = '';
res.on('data', function(chunk) {
content += chunk;
});
res.on('end', function() {
return content;
});
}).on('error', function() {
return null;
});
}
download2 returnează întotdeauna undefined. De ce?
Răspuns #1
Acestea sunt funcții asincrone. Ele s-au finalizat deja de mult timp înainte ca funcțiile callback să fie apelate. Prin urmare, rezultatul dorit al returnării nu este cunoscut atunci când oricare dintre funcțiile tale de descărcare se întoarce. Pentru datele transmise către callback-urile asincrone, SINGURUL loc în care poți face ceva cu aceste date este din callback-ul însuși. Poți să pui codul tău pentru a gestiona aceste date în callback sau poți să apelezi o altă funcție din interiorul callback-ului și să îi transmiți datele.
Aceasta este programarea asincronă și trebuie cu adevărat să te obișnuiești cu ea în Node pentru că este folosită mult acolo. Este semnificativ diferită de programarea sincronă în sensul că nu poți apela o funcție care pornește o operațiune asincronă și să te aștepți ca funcția părinte să obțină rezultatul și să-l returneze. Rezultatul operațiunii asincrone nu va fi cunoscut decât mai târziu, mult după ce funcția părinte a returnat deja.
Astfel, modul în care l-ai structurat în prima ta funcție download() este modul obișnuit de a gestiona acest lucru.