Prosty przykład wywołania zwrotnego nodeJs

120

Czy ktoś może mi podać prosty przykład wywołań zwrotnych nodeJs? Szukałem już tego samego na wielu stronach internetowych, ale nie jestem w stanie tego poprawnie zrozumieć, Proszę podać prosty przykład.

getDbFiles(store, function(files){
    getCdnFiles(store, function(files){
    })
})

Chcę zrobić coś takiego ...

Bhushan Goel
źródło
przykład, jak napisać funkcję, która jako argument przyjmuje wywołanie zwrotne?
Gntem
tak, coś takiego, jakikolwiek prosty przykład, który pomoże mi to zrozumieć.
Bhushan Goel
2
Callback to funkcja, którą przekazujesz jako parametr do innej funkcji ... Google pls -> "callback javascript" -> pierwszy wynik
Gabriel Llamas

Odpowiedzi:

198
var myCallback = function(data) {
  console.log('got data: '+data);
};

var usingItNow = function(callback) {
  callback('get it?');
};

Teraz otwórz węzeł lub konsolę przeglądarki i wklej powyższe definicje.

Na koniec użyj go z następną linią:

usingItNow(myCallback);

Z poszanowaniem konwencji błędów w stylu węzła

Costa zapytał, jak by to wyglądało, gdybyśmy przestrzegali konwencji wywołania zwrotnego błędu węzła.

W tej konwencji wywołanie zwrotne powinno oczekiwać otrzymania co najmniej jednego argumentu, pierwszego argumentu, jako błędu. Opcjonalnie będziemy mieć jeden lub więcej dodatkowych argumentów, w zależności od kontekstu. W tym przypadku kontekstem jest powyższy przykład.

Tutaj przepisuję nasz przykład w tej konwencji.

var myCallback = function(err, data) {
  if (err) throw err; // Check for the error and throw if it exists.
  console.log('got data: '+data); // Otherwise proceed as usual.
};

var usingItNow = function(callback) {
  callback(null, 'get it?'); // I dont want to throw an error, so I pass null for the error argument
};

Jeśli chcemy zasymulować przypadek błędu, możemy zdefiniować usingItNow w ten sposób

var usingItNow = function(callback) {
  var myError = new Error('My custom error!');
  callback(myError, 'get it?'); // I send my error as the first argument.
};

Końcowe użycie jest dokładnie takie samo jak powyżej:

usingItNow(myCallback);

Jedyna różnica w zachowaniu byłaby usingItNowzależna od tego, która wersja została zdefiniowana: ta, która przekazuje „prawdziwą wartość” (obiekt Error) do wywołania zwrotnego dla pierwszego argumentu, czy ta, która przekazuje mu wartość zerową dla argumentu błędu .

keyvan
źródło
Jak to wygląda z błędem jako konwencją pierwszego parametru?
Costa
113

Funkcja zwrotna to po prostu funkcja, którą przekazujesz do innej funkcji, aby funkcja mogła ją wywołać w późniejszym czasie. Jest to często widoczne w asynchronicznych interfejsach API ; wywołanie API wraca natychmiast, ponieważ jest asynchroniczne, więc przekazujesz do niego funkcję, którą interfejs API może wywołać po zakończeniu wykonywania zadania asynchronicznego.

Najprostszym przykładem, jaki przychodzi mi do głowy w JavaScript, jest setTimeout()funkcja. Jest to funkcja globalna, która przyjmuje dwa argumenty. Pierwszy argument to funkcja zwrotna, a drugi argument to opóźnienie w milisekundach. Funkcja została zaprojektowana tak, aby czekać przez odpowiednią ilość czasu, a następnie wywołać funkcję zwrotną.

setTimeout(function () {
  console.log("10 seconds later...");
}, 10000);

Być może widziałeś już powyższy kod, ale po prostu nie zdawałeś sobie sprawy, że funkcja, którą przekazujesz, nazywa się funkcją zwrotną. Moglibyśmy przepisać powyższy kod, aby był bardziej oczywisty.

var callback = function () {
  console.log("10 seconds later...");
};
setTimeout(callback, 10000);

Wywołania zwrotne są używane w Node w każdym miejscu, ponieważ Node jest zbudowany od podstaw, aby był asynchroniczny we wszystkim, co robi. Nawet podczas rozmowy z systemem plików. Dlatego mnóstwo wewnętrznych interfejsów API Node akceptuje funkcje zwrotne jako argumenty, zamiast zwracać dane, które można przypisać do zmiennej. Zamiast tego wywoła funkcję zwrotną, przekazując żądane dane jako argument. Na przykład możesz użyć fsbiblioteki Node do odczytania pliku. fsModuł wystawia dwie unikalne funkcje API: readFilea readFileSync.

readFileFunkcja jest asynchroniczny, gdy readFileSyncnie jest oczywisty. Możesz zobaczyć, że zamierzają używać wywołań asynchronicznych, gdy tylko jest to możliwe, ponieważ je wywołali, readFilea readFileSynczamiast readFilei readFileAsync. Oto przykład użycia obu funkcji.

Synchroniczny:

var data = fs.readFileSync('test.txt');
console.log(data);

Powyższy kod blokuje wykonywanie wątku, dopóki cała zawartość nie test.txtzostanie wczytana do pamięci i zapisana w zmiennej data. W węźle jest to zwykle uważane za złą praktykę. Są jednak chwile, kiedy jest to przydatne, na przykład podczas pisania krótkiego, małego skryptu, aby zrobić coś prostego, ale żmudnego, i nie zależy ci zbytnio na oszczędzaniu każdej nanosekundy, jaką możesz.

Asynchroniczne (z wywołaniem zwrotnym):

var callback = function (err, data) {
  if (err) return console.error(err);
  console.log(data);
};
fs.readFile('test.txt', callback);

Najpierw tworzymy funkcję zwrotną, która przyjmuje dwa argumenty erri data. Jednym z problemów związanych z funkcjami asynchronicznymi jest to, że przechwytywanie błędów staje się trudniejsze, więc wiele funkcji API w stylu wywołań zwrotnych przekazuje błędy jako pierwszy argument funkcji wywołania zwrotnego. Najlepiej jest sprawdzić, czy errma wartość, zanim zrobisz cokolwiek innego. Jeśli tak, zatrzymaj wykonywanie wywołania zwrotnego i zarejestruj błąd.

Połączenia synchroniczne mają przewagę, gdy występują wyjątki, ponieważ można je po prostu złapać za pomocą try/catchbloku.

try {
  var data = fs.readFileSync('test.txt');
  console.log(data);
} catch (err) {
  console.error(err);
}

W funkcjach asynchronicznych nie działa to w ten sposób. Wywołanie API wraca natychmiast, więc nie ma nic do złapania z try/catch. Właściwe asynchroniczne interfejsy API, które używają wywołań zwrotnych, zawsze wychwytują własne błędy, a następnie przekazują je do wywołania zwrotnego, gdzie można je obsłużyć według własnego uznania.

Oprócz wywołań zwrotnych istnieje jednak inny popularny styl interfejsu API, który jest powszechnie używany, zwany obietnicą. Jeśli chcesz o nich poczytać, możesz przeczytać cały wpis na blogu, który napisałem na podstawie tej odpowiedzi tutaj .

Chev
źródło
3
dość rozbudowane, ale zwięzłe przedstawienie koncepcji; dla startera node.js takiego jak ja ...
kmonsoor
3
+1 za zapewnienie dużej ilości kontekstu. Nie tylko jak wyglądają funkcje zwrotne, ale czym są, dlaczego są używane i dlaczego są często używane. Naprawdę pomocne dla początkującego.
Azurespot
1
Wspaniały! to może być sam post!
Pablo Glez
1
Jest i zawiera drugą część o obietnicach;)
Chev
1
To znacznie lepsze wyjaśnienie niż akceptowana odpowiedź! Chciałbym, żeby każda zaakceptowana odpowiedź w SO była taka - nie tylko fragment kodu, który rozwiązuje problem, ale także DLACZEGO i JAK rozwiązuje problem. Zasadniczo ta odpowiedź i wywołanie zwrotne dałyby całkiem solidne zrozumienie tego, czym jest wywołanie zwrotne.
RusI
10

Oto przykład kopiowania pliku tekstowego za pomocą fs.readFilei fs.writeFile:

var fs = require('fs');

var copyFile = function(source, destination, next) {
  // we should read source file first
  fs.readFile(source, function(err, data) {
    if (err) return next(err); // error occurred
    // now we can write data to destination file
    fs.writeFile(destination, data, next);
  });
};

A to przykład użycia copyFilefunkcji:

copyFile('foo.txt', 'bar.txt', function(err) {
  if (err) {
    // either fs.readFile or fs.writeFile returned an error
    console.log(err.stack || err);
  } else {
    console.log('Success!');
  }
});

Wspólny wzorzec node.js sugeruje, że pierwszy argument funkcji zwrotnej jest błędem. Powinieneś użyć tego wzorca, ponieważ wszystkie moduły sterowania przepływem na nim polegają:

next(new Error('I cannot do it!')); // error

next(null, results); // no error occurred, return result
Leonid Beschastny
źródło
2
co jest następne? Co to jest zmienna wyniki = jak się nazywa?
The Nomadic Coder
3
@SemicolonWarrier wskaźnik dla mnie i innych: stackoverflow.com/questions/5384526/javascript-node-js-next
kmonsoor
7

Wypróbuj ten przykład tak prosty, jak tylko potrafisz, po prostu skopiuj save newfile.js do node newfile, aby uruchomić aplikację.

function myNew(next){
    console.log("Im the one who initates callback");
    next("nope", "success");
}


myNew(function(err, res){
    console.log("I got back from callback",err, res);
});
spacedev
źródło
3

tworzymy prostą funkcję jak

callBackFunction (data, function ( err, response ){
     console.log(response)
}) 

// callbackfunction 
function callBackFuntion (data, callback){
    //write your logic and return your result as
callback("",result) //if not error
callback(error, "") //if error
}
saurabh kumar
źródło
1
const fs = require('fs');

fs.stat('input.txt', function (err, stats) {
    if(err){
        console.log(err);
    } else {
        console.log(stats);
        console.log('Completed Reading File');
    }
});

„fs” to moduł węzła, który pomaga w czytaniu pliku. Funkcja wywołania zwrotnego zapewni, że plik o nazwie „input.txt” zostanie w całości odczytany, zanim zostanie wykonany. Funkcja fs.stat () służy do pobierania informacji o pliku, takich jak rozmiar pliku, data utworzenia i data modyfikacji.

Anuj Kumar
źródło
1

//delay callback function
function delay (seconds, callback){
    setTimeout(() =>{
      console.log('The long delay ended');
      callback('Task Complete');
    }, seconds*1000);
}
//Execute delay function
delay(1, res => {  
    console.log(res);  
})

Surojit Paul
źródło
0

A callbackto funkcja przekazana jako parametr do Higher Order Function( wikipedia ). Prosta implementacja wywołania zwrotnego to:

const func = callback => callback('Hello World!');

Aby wywołać funkcję, po prostu przekaż inną funkcję jako argument do zdefiniowanej funkcji.

func(string => console.log(string));
toondaey
źródło