Advertisement
ReutenkoIvan

basic promise knowledge in JS

Oct 28th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.63 KB | None | 0 0
  1. И так, что такое промисы. Вот какое определение есть на MDN:
  2.  
  3. Интерфейс Promise (промис) представляет собой обертку для значения, неизвестного на момент создания промиса. Он позволяет обрабатывать результаты асинхронных операций так, как если бы они были синхронными: вместо конечного результата асинхронного метода возвращается обещание (промис) получить результат в некоторый момент в будущем.
  4.  
  5. --------------------------------------------------------------------------------------------------------------------------
  6. На что стоит обратить внимание при изучении промисов:
  7. __________
  8. Promise это класс у которого есть СТАТИЧЕСКИЕ МЕТОДЫ:
  9. all,race, resolve, reject
  10.  
  11. Как их использовать? так же как и другие статические методы классов - вызывать напрямую из класса
  12. Promise.all([promise1, promise2])
  13. Promise.resolve(resolvedValue)
  14.  
  15. Также у класса Promise есть МЕТОДЫ ЗАПИСАННЫЕ В ПРОТОТИП
  16. then, catch, finally
  17.  
  18. Как использовать? так же как и другие методы из прототипов - создать экземпляр класса и вызвать на нём
  19. const miniPromise = Promise.resolve(1)
  20. miniPromise.then(console.log)
  21. __________
  22.  
  23. функции-обработчики из then, catch и finally возвращают промис
  24. функция-обработчик метода finally не принемает аргументов
  25. Promise.resolve(2).finally(data => console.log(data)) // undefined
  26. __________
  27.  
  28. Когда создаем инстанс (экземпляр) промиса - тело промиса синхронное, aсинхронным является только обработка результата
  29.  
  30. console.log(1)
  31.  
  32. const prettyPromise = new Promise(resolve => {
  33. console.log(2)
  34. resolve('awesome')
  35. })
  36.  
  37. prettyPromise.then((res) => console.log(4)) // res === 'awesome'
  38.  
  39. console.log(3)
  40.  
  41.  
  42. --------------------------------------------------------------------------------------------------------------------------
  43. Лучшие практики:
  44. 1. Если нужно просто промисофицировать какое нибудь значение лучше использовать
  45. Promise.resolve(value) или Promise.reject(value), а не
  46. new Promise(resolve => resolve(value)) или new Promise((resolve, reject) => reject(value))
  47.  
  48. 2. Лучше не использовать сразу оба аргумента в методе then для обработки результата
  49. Почему: если произойдет ошибка при исполнении кода функции навешеной на успешный результат промиса,
  50. то функция на reject промиса не сможет поймать эту ошибку:
  51.  
  52. Promise.resolve(2).then(
  53. res => { throw new Error('stupid error') },
  54. err => { console.log(err) } // Ошибка? Какая ошибка? ничего не знаю
  55. )
  56.  
  57. Решение: использовать catch
  58.  
  59. Promise.resolve(2)
  60. .then(res => { throw new Error('stupid error') })
  61. .catch(err => { console.log(err) }) поймали эту 'stupid error'
  62.  
  63. 3. Когда использоать Promise.race?
  64. честно сказать почти бесполезный метод, для себя я нашел два кейса:
  65. * Если нужно подключить файл который хостится одновременно на нескольких серверах.
  66. Делаем запрос на получение файла из нескольких API -> оборачиваем это в Promise.race -> в итоге получаем один файл который загрузился быстрее всех
  67. * Если нужно поставить таймер на обработку функции, которая возвращает промис
  68.  
  69. Promise.race([
  70. new Promise(function (resolve, reject) {
  71. setTimeout(reject, 10000); // timeout after 10 secs
  72. }),
  73.  
  74. doSomethingThatMayTakeAwhile()
  75. ]);
  76.  
  77. 4. Если нужно использовать результаты одного промиса для создания другого или нужно указать порядок обработки результатов промисов используют промис чейнинг(promise chaining)
  78. вот пример последовательного получения данных с API
  79.  
  80. const urls = [
  81. 'https://jsonplaceholder.typicode.com/todos/1',
  82. 'https://jsonplaceholder.typicode.com/todos/2',
  83. ];
  84.  
  85. function sequentialRequest(urls){
  86. const results = [];
  87.  
  88. const chain = urls.reduce((chain, url) => chain.then(() => fetch(url))
  89. .then(response => response.json())
  90. .then(data => {results.push(data)})
  91. .catch(data => {results.push(data)})
  92. , Promise.resolve());
  93.  
  94. return chain.then(() => results); // ждем пока последний промис в цепочке обработается и возвращаем промисофицированый // результат что бы можно было обработать
  95. }
  96.  
  97. sequentialRequest(urls).then(console.log); // <---- then ожидает функцию в которую будет прокинут результат
  98.  
  99. --------------------------------------------------------------------------------------------------------------------------
  100. Подводные камни:
  101. 1. then ожидает только функцию! если передать не функцию результат прокинется в следующий then (это называется проваливание)
  102.  
  103. Promise.resolve(2).then(console.log) // выведет 2 в консоль
  104.  
  105. Promise.resolve(3)
  106. .then(Promise.resolve(1)) // промис !== функция -> предыдущий результат "проваливается"
  107. .then(console.log) // выведет 3 в консоль
  108.  
  109. 2. Если из then возвращается промис, то он просто передается в следующий обработчик, если ничего не возвращается или возвращается не промис, то результат функции оборачивается в Promise.resolve
  110.  
  111. Promise.resolve(2)
  112. .then(res => {
  113. const nextValue = res * 2;
  114. return nextValue // внутри происходит return Promise.resolve(nextValue) чтобы следующий then мог подписаться
  115. })
  116. .then(data => {
  117. console.log(data)
  118. })
  119.  
  120. Promise.resolve(3)
  121. .then(res => {
  122. const nextValue = res === 3 ? Promise.reject(2) : 12 // res равно 3 -> nextValue присваивается Promise.reject(2)
  123. return nextValue // из функции возвращается промис -> внутри не оборачивается
  124. })
  125. .then(console.log) // пропускает так как состояние промиса на который подписан - reject
  126. .catch(console.log) // выводит в консоль 2
  127.  
  128. --------------------------------------------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement