Не то же самое
function ajax() {
return fetch(target, fetchOptions)
.then((response) => {
if (!target) throw new Error('Invalid url');
if (response.ok) return response.json();
throw new Error(`${response.status} ${response.statusText}`);
})
.then((json) => {
if (json['statusOk']) return json;
throw new Error(json['message'] || 'Server response was not ok');
});
}
ajax(action, { body: formData })
.then((json) => {
console.log('RESPONSE', json);
})
.catch((error) => {
console.error(error);
});
Мы можем писать сколько угодно зенов, в каждом что-то делать с данными.
Если в любом месте вылетит ошибка, она будет нормально обработана в кэтче.
Код при этом линейный, без дикой вложенности.
С коллбэками вам нужно на каждом этапе отслеживать ошибки и возвращать их. Легко потеряться, что откуда всплыло или где пропало.
Альтернатива обработки ошибок — трай/кэтч. Но это не работает на асинхронном коде.
function myFunc(cb){
var err = true;
// имитируем асинхронную операцию
setTimeout(function(){
cb(err);
}, 10);
}
try {
myFunc(function(err){
if (err) throw new Error('Oops');
});
alert('Всё как бы хорошо!');
} catch(e) {
alert(e.message);
}
Этот код выведет сообщение 'Всё как бы хорошо!', хотя всё плохо, была ошибка.
https://jsfiddle.net/r3zfa4ee/
С промисами иначе:
function myFunc(){
let promise = new Promise((resolve, reject) => {
let err = true;
// имитируем асинхронную операцию
setTimeout(() => {
if (err) {
reject('Ooops!');
} else {
resolve(123);
}
}, 10);
});
return promise;
}
myFunc()
.then(data => {
alert('Всё точно хорошо!');
})
.catch(e => {
alert(e);
});
Здесь уже ошибка будет обработана как надо и мы увидим сообщение 'Ooops!'
https://jsfiddle.net/43yh8jad/
Мы можем выполнить промисы последовательно. Мы можем выполнить их параллельно. Мы можем запустить их на параллельное выполнение, но дождаться только первого отработавшего (так называемая promise race). Разумеется всё это можно и без промисов написать, но какая будет разница в объеме кода и в сложности его понимания?
А еще есть async/await...