Что такое Промисы?

Промис - это объект который дает тебе описать как работать с данными которые еще не появились программе.

Например у тебя есть магазин. Фронтенде ты показываешь количество продуктов. Пусть это значение получается асинхронно (может 1 или несколько запросов). Тогда чтобы описать получение количества продуктов ты пишешь код вида, где возвращаешь Promise. В момент возврата промис еще не зарезолвлен (не resolved), нет значения прикрепленного к нему. Зато у него есть методы .then, .catch через которые потребиталь может описать функции которые выполнятся когда в промисе появится значение (устанавливается с помощью вызова resolve).

function getProductsCount() {
	return new Promise(function (resolve, reject) {
		//...

		//...
	})
}

А потребитель количества продуктов описать что он будет делать когда значение вычислится (когда промис зарезолвится). Именно эту мезанику я имею в виду когда говорю “объект который дает тебе описать как работать с данными которые еще не появились программе”.

getProductsCount().then(function (productCount) {
	$('.product-count').text(productCount)
})

Использование в ajax-е - не единственное место для промисов. Они нужны почти в любом асинхронном API: например на сервере промисы ипользуются для описания результатов вызовов базы данных, файловой системы. С помощью промисов удобно моделировать множественные запросы в виде одного промиса: это когда нужно сделать 5-10 запросов на сервер и работать с результатом всех запросов.


Разные задачи, но не взаимоисключающие. Ситуация именно такая как выглядит: с помощью catch ты описываешь только обработчик для ошибки. С помощью then ты описываешь обработчик для успеха а так же можешь описать обработчик для ошибки.


Ты всегда передаешь функции в promise чтобы он их контролировал. Воспро оборачивания не стоит, обращай внимание где функции передаются аргументами.

Ты передаешь функцию в промис, он контролирует когда ее вызвать. При ее вызове он контролирует какие функции передать в аргументы вызванной функции. Эти функции будут в переменных resolve, reject и уже ты определяешь когда их вызывать. Их вызов даст сигнал промису что или значение получено или ошибка

const p = new Promise(function (resolve, reject) {
    //....
})

И при использовании промиса через его методы ты тоже даешь функцию чтобы ее контролировал промис:

p.then(function (res) {
    console.log(res)
})

var isNetworkOK = true;
 
function downloadFile(url)  {      // Обязательно оборачивать в функцию Promise? Что это даёт?
// это дает возможность получить сколько угодно промисов, параметрезировав запрос по url.
// если не использовать функции то ты опишешь промис для 1 конкретного урла.
// с функцией ты можешь описать получение промисов для разных урлов (соответственно загрузку любого файла по урлу)
    console.log("Start downloading file ..."); // ***
 
    // A Promise
    var willIGetAFile = new Promise (
        function (resolve, reject) {
 
            if (isNetworkOK) {
                setTimeout( function() {
                    console.log("Complete the download process!"); // ***
                    var file = {
                        fileName: 'file.mp3',
                        fileContent: '...',
                        fileSize: '3 MB'
                    };
                    resolve(file); // resolve всегда должен возвращать объект?
// нет. Это может быть примитив: число, boolean итд.
                }, 5 * 1000); 
            } else {
                var error = new Error('There is a problem with the network.');
                reject(error); 
            }
        }
    );
    return willIGetAFile; // Зачем возвращать Promise? Разве он не был возвращён на 18 строке? ( resolve(file) )
// забудь на секунду про промисы и посмотри на синтаксические конструкции как на функции и объекты
// в какой строке функция downloadFile возвращает значение? (подсказка - не в 18). 
// теперь можешь вспомнить про промисы: return нужен чтобы результат работы функции был тем что справа от `return` - объект
// которым ниже потребитель будет пользоваться чтобы описать что делать с результатом. 

// в18 строке устанавлиается значение промиса, это не тоже самое что вернуть объект промиса
}
 
 // те же вопросы касаются и функции ниже
// те же ответы
function openFile(file) {
    console.log("Start opening file ..."); // ***
 
    var willFileOpen = new Promise(
        function (resolve, reject) {
             var message = "File " + file.fileName + " opened!"
             resolve(message);
        }
    );
 
    return willFileOpen;
}
 
console.log("Start app.."); // ***
 
// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3"); // Что здесь происходит? Мы что, перетираем промис на 7 строчке?

// мы записываем в willIGetAFile инстанс промиса (это у которого методы then и catch)
// этот объект представляет "обещаение" данных, и мы можем описать что мы хотим делать с данными если/когда они появятся.
 
 
willIGetAFile  // Здесь уже находится не промис, а downloadFile("http://example.com/file.mp3") И у него вызывается then... Почему?
// Здесь уже находится не промис, а downloadFile("http://example.com/file.mp3") - в чем разница?
// promise - это значение (вернее тип значения), downloadFile("http://example.com/file.mp3") - результат вызова функции, значение, значение типа промис.  Тут нет противоречия
        .then(openFile) // Chain it!
        .then(function (fulfilled) { // If successful fileOpen.
            // Get a message after file opened!
            // Output: File file.mp3 opened!
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });
 
console.log("End app.."); // ***
2 лайка