Как преобразовать существующий обратный вызов в обещание в Node.js?

Опубликовано: 4 Августа, 2021

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

Пример: лучший пример для демонстрации этого - использование функции setTimeout (), которая принимает обратный вызов и задерживает выполнение кода JavaScript. Как только время, установленное для работы, истекает, выполняется функция обратного вызова.




// Defining a callback function
var callback = ()=>{
console.log( "Hello! GeeksforGeeks" );
}
// Passing the callback function
// as a parameter
setTimeout(callback, 2000);
// The callback gets executed as
// soon as 2 seconds are over.
// This behavior shows the
// execution of a callback.

Выход:

 Привет! GeeksforGeeks

Обещания: это очень похоже на обратные вызовы в работе. Но преимущество использования Promises заключается в улучшении читабельности кода, так как это избавляет нас от ада обратных вызовов.
Обещания имеют четыре состояния

  • В ожидании: обещание еще не выполнено. Не получилось и провалилось.
  • Выполнено: обещание завершилось успехом.
  • Отклонено: обещание завершилось ошибкой.
  • Урегулировано: обещание либо выдало ошибку, либо выполнено успешно.

Преобразование существующего обратного вызова в обещание:




// Existing Callback
var callback = function(err, success) {
    if(err) {
        console.log("Geek is very sad!");
    }
    else {
        console.log("Geek is optimistic, "
            + "thus becomes successful");
    }
}
   
var caller = function(status, callback){
    if(status === "Happy")
        callback(null, true);
    else {
        callback(new Error(), false);
    
}
   
// Calling the caller method
  
// Executes the success part
caller("Happy", callback);
  
// Executes the error part
caller("Sad", callback);

Выход:

 Компьютерщик оптимистичен, поэтому становится успешным
Компьютерщику очень грустно!

Действия, которые необходимо выполнить:

  • Определите функцию с именем error и вставьте в нее блок кода ошибки функции обратного вызова.
  • Определите функцию с именем success и вставьте в нее кодовый блок успеха.
  • Затем измените код вызывающего абонента, вернув объект обещания.
  • Используйте методы успеха и ошибки любым из следующих способов.
  • См. Фрагмент кода ниже для лучшего понимания.




// This snippet briefly shows
// the implementation
var error = function (){
// The error codeblock from
// the existing callback.
console.log( "Geek is very sad!" );
}
var success = function (){
// The success codeblock from
// the existing callback
console.log( "Geek is optimistic, "
+ "thus becomes successful" );
}
var caller = function (status) {
return new Promise( function (resolve, reject) {
if (status === 'Happy' ) {
// Calling the resolve function
// when function returns success
resolve();
}
else {
// Calling the reject function
// when function returns failure
reject();
}
});
};
// Throw success
caller( 'Happy' ).then(success). catch (error);
// Throw error
caller( 'Sad' ).then(success). catch (error);

Выход:

 Компьютерщик оптимистичен, поэтому становится успешным
Компьютерщику очень грустно!

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

Чтобы понять, используя пример, нам нужно настроить сервер узла в системе. Вы можете выполнить следующие шаги, чтобы настроить сервер узла.

Установите узел и настройте приложение простого узла, выполнив шаги, как показано здесь.

Пример: здесь сценарий состоит в том, что у нас есть массив учеников с идентификатором и именем в качестве значений. Нам нужно получить имя студента, имеющего данный идентификатор. Нам дается существующий обратный вызов, который необходимо преобразовать в обещание.




/* The following code snippet depicts a GET request
to the server made by the client, which requests for
the name of the student with a given student id. Here we
have a student array that stores JSON objects of
student id and name. We are going to create a GET
Request using expressjs in node first. Then we will
write a route to get name of student based on id. */
const express = require( 'express' );
const app = express();
// Students array
var students = [
{
id: 101,
name: "Geek A"
},
{
id: 102,
name: "Geek B"
},
{
id: 103,
name: "Geek C"
},
{
id: 104,
name: "Geek D"
}
];
// Definition of the callback function
const callback = (err, student) => {
if (err) {
return `Student with given id ${err} not found`;
}
else {
return "Here is the student: " + student.name;
}
}
// Passing studentid and callback function as parameter
const findName = (studentId, callbackFunction) => {
let student = students.find( function (studentValue) {
return studentValue.id == studentId;
});
// Student not found
if ( typeof student === 'undefined' ) {
return callbackFunction(studentId, false );
}
else { // Student found
return callbackFunction( null , student);
}
}
const getName = (req, res)=>{
// Sending back the response to the server
res.send(findName(req.params.studentId, callback));
}
app.get( '/getName/:studentId' , getName);
app.listen(8000, 'localhost' , function () {
console.log( 'Server Listening' );
});

Выход:

Теперь мы можем преобразовать функцию обратного вызова в обещания. Здесь мы можем снова выполнить предыдущие шаги, то есть логику ошибки в функции отказа и логику успеха в функции успеха. Пожалуйста, просмотрите приведенный ниже код для большей ясности.




const express = require( 'express' );
const app = express();
var students = [
{
id: 101,
name: "Geek A"
},
{
id: 102,
name: "Geek B"
},
{
id: 103,
name: "Geek C"
},
{
id: 104,
name: "Geek D"
}
];
// Writing the success logic here
const success = (student) => {
return "Here is the student: " + student.name;
}
// Writing the failure logic here.
const failure = (fail) => {
return `Student with the given id ${fail} was not found`;
}
const findName = (studentId) => {
return new Promise( function (resolve, reject) {
let student = students.find( function (studentValue) {
return studentValue.id == studentId;
});
if (student) {
resolve(student);
}
else {
reject(id);
}
});
}
const getName = async (req, res) => {
let answer = await findName(
req.params.studentId).then(success). catch (failure);
res.send(answer);
}
app.get( '/getName/:studentId' , getName);
app.listen(8000, 'localhost' , function () {
console.log( 'Server Listening' );
});

Выход: