Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- И так, что такое промисы. Вот какое определение есть на MDN:
- Интерфейс Promise (промис) представляет собой обертку для значения, неизвестного на момент создания промиса. Он позволяет обрабатывать результаты асинхронных операций так, как если бы они были синхронными: вместо конечного результата асинхронного метода возвращается обещание (промис) получить результат в некоторый момент в будущем.
- --------------------------------------------------------------------------------------------------------------------------
- На что стоит обратить внимание при изучении промисов:
- __________
- Promise это класс у которого есть СТАТИЧЕСКИЕ МЕТОДЫ:
- all,race, resolve, reject
- Как их использовать? так же как и другие статические методы классов - вызывать напрямую из класса
- Promise.all([promise1, promise2])
- Promise.resolve(resolvedValue)
- Также у класса Promise есть МЕТОДЫ ЗАПИСАННЫЕ В ПРОТОТИП
- then, catch, finally
- Как использовать? так же как и другие методы из прототипов - создать экземпляр класса и вызвать на нём
- const miniPromise = Promise.resolve(1)
- miniPromise.then(console.log)
- __________
- функции-обработчики из then, catch и finally возвращают промис
- функция-обработчик метода finally не принемает аргументов
- Promise.resolve(2).finally(data => console.log(data)) // undefined
- __________
- Когда создаем инстанс (экземпляр) промиса - тело промиса синхронное, aсинхронным является только обработка результата
- console.log(1)
- const prettyPromise = new Promise(resolve => {
- console.log(2)
- resolve('awesome')
- })
- prettyPromise.then((res) => console.log(4)) // res === 'awesome'
- console.log(3)
- --------------------------------------------------------------------------------------------------------------------------
- Лучшие практики:
- 1. Если нужно просто промисофицировать какое нибудь значение лучше использовать
- Promise.resolve(value) или Promise.reject(value), а не
- new Promise(resolve => resolve(value)) или new Promise((resolve, reject) => reject(value))
- 2. Лучше не использовать сразу оба аргумента в методе then для обработки результата
- Почему: если произойдет ошибка при исполнении кода функции навешеной на успешный результат промиса,
- то функция на reject промиса не сможет поймать эту ошибку:
- Promise.resolve(2).then(
- res => { throw new Error('stupid error') },
- err => { console.log(err) } // Ошибка? Какая ошибка? ничего не знаю
- )
- Решение: использовать catch
- Promise.resolve(2)
- .then(res => { throw new Error('stupid error') })
- .catch(err => { console.log(err) }) поймали эту 'stupid error'
- 3. Когда использоать Promise.race?
- честно сказать почти бесполезный метод, для себя я нашел два кейса:
- * Если нужно подключить файл который хостится одновременно на нескольких серверах.
- Делаем запрос на получение файла из нескольких API -> оборачиваем это в Promise.race -> в итоге получаем один файл который загрузился быстрее всех
- * Если нужно поставить таймер на обработку функции, которая возвращает промис
- Promise.race([
- new Promise(function (resolve, reject) {
- setTimeout(reject, 10000); // timeout after 10 secs
- }),
- doSomethingThatMayTakeAwhile()
- ]);
- 4. Если нужно использовать результаты одного промиса для создания другого или нужно указать порядок обработки результатов промисов используют промис чейнинг(promise chaining)
- вот пример последовательного получения данных с API
- const urls = [
- 'https://jsonplaceholder.typicode.com/todos/1',
- 'https://jsonplaceholder.typicode.com/todos/2',
- ];
- function sequentialRequest(urls){
- const results = [];
- const chain = urls.reduce((chain, url) => chain.then(() => fetch(url))
- .then(response => response.json())
- .then(data => {results.push(data)})
- .catch(data => {results.push(data)})
- , Promise.resolve());
- return chain.then(() => results); // ждем пока последний промис в цепочке обработается и возвращаем промисофицированый // результат что бы можно было обработать
- }
- sequentialRequest(urls).then(console.log); // <---- then ожидает функцию в которую будет прокинут результат
- --------------------------------------------------------------------------------------------------------------------------
- Подводные камни:
- 1. then ожидает только функцию! если передать не функцию результат прокинется в следующий then (это называется проваливание)
- Promise.resolve(2).then(console.log) // выведет 2 в консоль
- Promise.resolve(3)
- .then(Promise.resolve(1)) // промис !== функция -> предыдущий результат "проваливается"
- .then(console.log) // выведет 3 в консоль
- 2. Если из then возвращается промис, то он просто передается в следующий обработчик, если ничего не возвращается или возвращается не промис, то результат функции оборачивается в Promise.resolve
- Promise.resolve(2)
- .then(res => {
- const nextValue = res * 2;
- return nextValue // внутри происходит return Promise.resolve(nextValue) чтобы следующий then мог подписаться
- })
- .then(data => {
- console.log(data)
- })
- Promise.resolve(3)
- .then(res => {
- const nextValue = res === 3 ? Promise.reject(2) : 12 // res равно 3 -> nextValue присваивается Promise.reject(2)
- return nextValue // из функции возвращается промис -> внутри не оборачивается
- })
- .then(console.log) // пропускает так как состояние промиса на который подписан - reject
- .catch(console.log) // выводит в консоль 2
- --------------------------------------------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement