Javascript: больше никаких обратных вызовов, используйте Promisify для преобразования обратного вызова в обещание
20 ноября 2022 г.Что такое обратный вызов и обещание?
Обратный вызов — это функция, которая передается в качестве параметра другой функции. И эта функция будет вызываться внутри функции.
Промис — это объект, используемый для обработки асинхронных операций. Он используется для обработки нескольких асинхронных операций, которые могут зависеть друг от друга.
Зачем нужны обратный вызов и обещание?
Обратный вызов и обещание используются для обработки асинхронных операций. Асинхронная операция — это операция, которая не выполняется немедленно. Выполняется через некоторое время. Например, если вы делаете запрос к серверу для получения каких-то данных, то для получения ответа от сервера потребуется некоторое время. Значит, нужно дождаться ответа. Если мы делаем несколько запросов к серверу, нам нужно дождаться всех ответов. Итак, нам нужно обрабатывать асинхронные операции.
Зачем нужно преобразовывать обратный вызов в обещание?
Нам нужно преобразовать обратный вызов в промис, потому что промис более удобочитаем и прост в обращении. Мы можем обрабатывать несколько асинхронных операций с помощью promise. Мы также можем обрабатывать асинхронные операции, которые зависят друг от друга, используя обещание.
Давайте разберемся с этим на примере.
Предположим, у нас есть простая функция добавления, которая принимает два числа и возвращает сумму этих двух чисел в функции обратного вызова. Я также добавил функцию setTimeout для имитации асинхронного поведения функции.
Примечание. Я создаю стандартную функцию обратного вызова с первой ошибкой. В стандартной функции обратного вызова error first первый параметр — это ошибка, а второй — результат.
function add(a, b, callback) {
setTimeout(() => callback(null, a + b), 100);
}
add(1, 2, (err, sum) => {
console.log(sum);
});
Это довольно простая функция. Мы получаем результат через 100 мс. Теперь предположим, что мы хотим добавить к результату еще одно число. Мы можем сделать это, передав результат другой функции.
add(1, 2, (err, first) => {
console.log(first);
add(first, 3, (err, second) => {
console.log(second);
add(second, 4, (err, finalResult) => {
console.log(finalResult);
});
});
});
Если мы используем функцию обратного вызова, нам нужно написать вложенную функцию обратного вызова для обработки асинхронных операций. Это не читается, и оно становится ковшом и ковшом по мере того, как мы добавляем больше асинхронных операций. Это также называется адом обратных вызовов.
Теперь мы знаем проблему с функцией обратного вызова. Давайте посмотрим, как мы можем решить эту проблему с помощью обещания.
Как преобразовать функцию обратного вызова в обещание?
Мы создадим функцию обещания, которая будет принимать функцию обратного вызова в качестве параметра и возвращать обещание. Существует множество доступных пакетов npm, которые можно использовать для преобразования функции обратного вызова в обещание. Но я покажу вам, как преобразовать функцию обратного вызова в обещание без использования какого-либо пакета npm. Node.js уже предоставляет служебную функцию под названием promisify, которую можно использовать для преобразования функции обратного вызова в обещание.
const promisify =
(fn) =>
(...args) =>
new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
Давайте посмотрим, как это работает.
function add(a, b, callback) {
setTimeout(() => callback(null, a + b), 100);
}
const addPromise = promisify(add);
const run = async () => {
const first = await addPromise(1, 2);
console.log(first);
const second = await addPromise(first, 3);
console.log(second);
const finalResult = await addPromise(second, 4);
console.log(finalResult);
};
Это намного читабельнее и проще в обращении. Мы также можем обрабатывать несколько асинхронных операций, которые зависят друг от друга, используя обещание.
Если вы используете node.js версии 8 или выше, вы можете использовать функцию util.promisify для преобразования функции обратного вызова в обещание.
const { promisify } = require("util");
const addPromise = promisify(add);
Спасибо, что прочитали 😊
Есть дополнительные вопросы? пожалуйста, оставьте комментарий.
Оригинал