Простой пример обратного вызова nodeJs


120

Может ли кто-нибудь дать мне простой пример обратных вызовов nodeJs, я уже искал то же самое на многих веб-сайтах, но не мог понять его должным образом. Пожалуйста, дайте мне простой пример.

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

Я хочу сделать что-то подобное ...


пример того, как написать функцию, которая принимает обратный вызов в качестве аргумента?
Gntem 02

да, что-то в этом роде, любой простой пример, который поможет мне это понять.
Bhushan Goel

2
Обратный вызов - это функция, которую вы передаете в качестве параметра другой функции ... Google pls -> "callback javascript" -> первый результат
Габриэль Лламас

Ответы:


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

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

Теперь откройте узел или консоль браузера и вставьте приведенные выше определения.

Наконец, используйте его со следующей строкой:

usingItNow(myCallback);

В отношении соглашений об ошибках в стиле узла

Коста спросил, как бы это выглядело, если бы мы соблюдали правила обратного вызова ошибок узла.

В этом соглашении обратный вызов должен ожидать получения по крайней мере одного аргумента, первого аргумента, как ошибки. При желании у нас будет один или несколько дополнительных аргументов, в зависимости от контекста. В данном случае контекст - это наш приведенный выше пример.

Здесь я переписываю наш пример в этом соглашении.

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
};

Если мы хотим смоделировать случай ошибки, мы можем определить usingItNow следующим образом

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

Окончательное использование точно такое же, как указано выше:

usingItNow(myCallback);

Единственное различие в поведении будет зависеть от того, какую версию usingItNowвы определили: та, которая передает «истинное значение» (объект Error) в обратный вызов для первого аргумента, или та, которая передает его null для аргумента ошибки. ,


Так как же это выглядит с ошибкой в ​​качестве первого параметра?
Коста

113

Функция обратного вызова - это просто функция, которую вы передаете другой функции, чтобы эта функция могла вызвать ее позже. Это обычно наблюдается в асинхронных API ; вызов API возвращается немедленно, потому что он асинхронный, поэтому вы передаете ему функцию, которую API может вызвать, когда он завершит выполнение своей асинхронной задачи.

Самый простой пример, который я могу придумать в JavaScript, - это setTimeout()функция. Это глобальная функция, которая принимает два аргумента. Первый аргумент - это функция обратного вызова, а второй аргумент - задержка в миллисекундах. Функция предназначена для ожидания подходящее количество времени, а затем вызывает функцию обратного вызова.

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

Возможно, вы видели приведенный выше код раньше, но просто не понимали, что передаваемая вами функция называется функцией обратного вызова. Мы могли бы переписать приведенный выше код, чтобы сделать его более очевидным.

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

Обратные вызовы используются в Node повсеместно, потому что Node построен с нуля, чтобы быть асинхронным во всем, что он делает. Даже при разговоре с файловой системой. Вот почему тонна внутренних API-интерфейсов Node принимает функции обратного вызова в качестве аргументов, а не возвращает данные, которые вы можете присвоить переменной. Вместо этого он вызовет вашу функцию обратного вызова, передавая данные, которые вы хотите, в качестве аргумента. Например, вы можете использовать fsбиблиотеку Node для чтения файла. fsМодуль предоставляет два уникальных функций API: readFileи readFileSync.

readFileФункция является асинхронным , а readFileSync, очевидно , нет. Вы можете видеть, что они предполагают, что вы будете использовать асинхронные вызовы, когда это возможно, поскольку они вызвали их, readFileа readFileSyncне readFileи readFileAsync. Вот пример использования обеих функций.

Синхронный:

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

Приведенный выше код блокирует выполнение потока до тех пор, пока все содержимое не test.txtбудет считано в память и сохранено в переменной data. В узле это обычно считается плохой практикой. Однако бывают случаи, когда это полезно, например, при написании небольшого небольшого скрипта, чтобы сделать что-то простое, но утомительное, и вы не заботитесь об экономии каждой наносекунды времени, которое вы можете.

Асинхронный (с обратным вызовом):

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

Сначала мы создаем функцию обратного вызова, которая принимает два аргумента errи data. Одна из проблем с асинхронными функциями заключается в том, что становится труднее отлавливать ошибки, поэтому многие API-интерфейсы в стиле обратного вызова передают ошибки в качестве первого аргумента функции обратного вызова. Лучше всего проверить, errимеет ли значение значение, прежде чем делать что-либо еще. Если да, остановите выполнение обратного вызова и зарегистрируйте ошибку.

Синхронные вызовы имеют преимущество, когда возникают исключения, потому что вы можете просто поймать их с помощью try/catchблока.

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

В асинхронных функциях это не работает. Вызов API возвращается немедленно, так что с помощью try/catch. Правильные асинхронные API-интерфейсы, использующие обратные вызовы, всегда отлавливают свои собственные ошибки, а затем передают их в обратный вызов, где вы можете обрабатывать их по своему усмотрению.

Однако, помимо обратных вызовов, существует еще один популярный стиль API, который обычно используется под названием обещание. Если вы хотите прочитать о них, вы можете прочитать всю запись в блоге, которую я написал на основе этого ответа здесь .


3
довольно продуманная, но краткая передача концепции; для начинающего node.js, как я ...
kmonsoor 09

3
+1 за предоставление большого контекста. Не только то, как выглядят функции обратного вызова, но и то, что они собой представляют, почему они используются и почему они используются часто. Действительно полезно для новичка.
Azurespot

1
Большой! это могло быть сообщение само по себе!
Пабло Глез

1
Он есть , и он включает в себя вторую часть о обещаниях;)
Чев

1
Это гораздо лучшее объяснение, чем принятый ответ! Я бы хотел, чтобы каждый принятый ответ здесь, на SO, был таким - не только фрагмент кода, который решает проблему, но также ПОЧЕМУ и КАК он решает проблему. По сути, этот ответ и обратный вызов дадут вам довольно четкое представление о том, что такое обратный вызов.
RusI

10

Вот пример копирования текстового файла с помощью fs.readFileи 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);
  });
};

И это пример использования copyFileфункции:

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!');
  }
});

Распространенный шаблон node.js предполагает, что первый аргумент функции обратного вызова является ошибкой. Вы должны использовать этот шаблон, потому что все модули потока управления полагаются на него:

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

next(null, results); // no error occurred, return result

2
что дальше? Что такое переменная results = что называется?
The Nomadic Coder

3
@SemicolonWarrier - указатель для меня, а также для других: stackoverflow.com/questions/5384526/javascript-node-js-next
kmonsoor

7

Попробуйте этот пример настолько простым, насколько вы можете прочитать, просто скопируйте save newfile.js do node newfile для запуска приложения.

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);
});

3

мы создаем простую функцию как

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
}

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' - это модуль узла, который помогает вам читать файл. Функция обратного вызова гарантирует, что ваш файл с именем 'input.txt' полностью прочитан, прежде чем он будет выполнен. Функция fs.stat () предназначена для получения информации о файле, такой как размер файла, дата создания и дата изменения.


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);  
})


0

A callback- это функция, переданная в качестве параметра Higher Order Function( википедия ). Простая реализация обратного вызова:

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

Чтобы вызвать функцию, просто передайте другую функцию в качестве аргумента определенной функции.

func(string => console.log(string));

0

У этого сообщения в блоге есть хорошая рецензия:

https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced

function doHomework(subject, callback) {
  alert(`Starting my ${subject} homework.`);
  callback();
}

function alertFinished(){
  alert('Finished my homework');
}

doHomework('math', alertFinished);

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.