Асинхронное программирование очень важно в JavaScript, но слишком много асинхронного программирования также приводит к проблеме вложенности обратных вызовов.
Что такое функция обратного вызова?
ajax(url, () => {});
Приведенный выше код является функцией обратного вызова. Функция как параметр должна зависеть от другой функции для выполнения вызова.
Но у функции обратного вызова есть ахиллесова пята, склонная к аду обратных вызовов (аду обратных вызовов).
Что такое ад обратного вызова?
let form = document.querySelector('form');
form.onsubmit = function (e) {
var name = document.querySelector('input').value;
$.ajax({
url: "http://demo.com/submit",
type:'POST',
data: {name: name},
success: function(res) {
if (res.code === 2000) {
var h1 = document.querySelector('h1').innerHTML;
h1.innerHTML = res.data.name;
}
}
});
}
Таким образом, функции вкладываются слой за слоем в качестве параметров, из-за чего блок кода выглядит огромным и непонятным, и невозможно сразу различить уровень структуры, что называется «ад обратных вызовов».
Основные проблемы и недостатки callback hell:
- Вложенные функции связаны, и как только они будут изменены, они повлияют на все тело.
- Когда много вложенных функций, становится сложно обрабатывать ошибки
- Функция обратного вызова используется для использования ошибок try...catch...capture, а не RETURN напрямую.
Как решить ад обратного вызова?
Основная причина в том, что из-за привычек кодирования разработчиков мы можем решить ее следующими способами:
- Сохраняйте стиль кода коротким, старайтесь использовать именованные функции и избегайте анонимных функций.
document.querySelector('form').onsubmit = onFormSubmit();
function onFormSubmit(e) {
var name = document.querySelector('input').value;
$.ajax({
url: "http://demo.com/submit",
type:'POST',
data: {name: name},
success: onSuccess(res)
});
}
function onSuccess(res){
if (res.code === 2000) {
var h1 = document.querySelector('h1').innerHTML;
h1.innerHTML = res.data.name;
}
}
- Модульность, разделение каждой независимой функции, инкапсуляция, упаковка в отдельный файл js, импорт через импорт
// formHandler.js
module.exports.formSubmit = onFormSubmit;
function onFormSubmit(e) {
var name = document.querySelector('input').value;
$.ajax({
url: "http://demo.com/submit",
type:'POST',
data: {name: name},
success: onSuccess(res)
});
}
function onSuccess(res){
if (res.code === 2000) {
var h1 = document.querySelector('h1').innerHTML;
h1.innerHTML = res.data.name;
}
}
// index.js
var formHandler = require('./formHandler');
document.querySelector('form').onsubmit = formHandler.formSubmit;
- Обрабатывайте каждую ошибку, кодируйте в соответствии со стандартными спецификациями
- Promise/Gengenerator/Async Function
В дополнение к обычным функциям обратного вызова, таким как асинхронная обработка, есть промисы, генераторы и асинхронная обработка асинхронной обработки.
Каковы характеристики промисов?
Обещание переводится как обещание, которое обещает точный ответ в будущем и в будущем, причем обещание имеет три состояния:- в ожидании
- завершено (решено)
- Отклонено (отклонено)
Государство обязалось изменить будущее, вы не можете изменить государство
Когда мы конструируем Promise, когда внутри кода конструктора выполняется сразу
new Promise((resolve, reject) => {
console.log('new Promise')
resolve('success')
})
console.log('finish');
// new Promise
// finish
Promise.resovle(1)
.then(res => {
console.log(res); // 1
return 2; // 包装成了 Promise.reslove(2)
})
.then(res => {
console.log(res); // 2
})
Обещания также решают проблему адского обратного вызова:
// old
ajax(url, () => {
// 处理逻辑
ajax(url1, () => {
// 处理逻辑
ajax(url2, () => {
// 处理逻辑
})
})
})
// new
ajax(url)
.then(res => {
console.log(res);
return ajax(url1);
})
.then(res => {
console.log(res);
return ajax(url2);
})
.then(res => console.log(res));
асинхронно и жду
Синхронизация ожидания синхронизируется только в асинхронной функции, но не блокирует выполнение другого внешнего кода. Вот почему ожидание должно быть помещено в асинхронную функцию.
async используется для объявления функции асинхронной, а await используется для ожидания завершения асинхронного метода.
Продолжение следует...