Обещания JavaScript часто используются в асинхронных функциях. Цель обещания — разрешить выполнение других процессов в ожидании завершения асинхронного действия.
Обещание является родным для JavaScript. Зайдите в консоль своего веб-браузера и введите «Promise», обязательно используйте заглавную «P» и нажмите Enter. Вы должны увидеть что-то близкое к этому…
f Promise() { [native code] }
Тот факт, что браузер знает, что такое промис, не объявляя его самостоятельно, означает, что промис встроен в язык JavaScript.
Что нам известно на данный момент?
- Обещания — это функции.
- Обещания используются для асинхронных процессов.
- Промисы встроены в язык JS.
Обещания — это функции? Правильно, промисы — это функции. native code
означает, что это часть языка JavaScript. Поскольку это нативный код, мы не сможем заглянуть под капот. Однако общая структура Promise такова:
let myPromise = new Promise( function executor( resolveFunction, rejectFunction) { // Here is where an async code block is added. })
ПРИМЕЧАНИЕ. То, что передается в параметр промиса, также является функцией, называемой «исполнитель». Если внимательно отследить, закрывающая скобка будет в самой последней строке, последний символ. Это известно как функция обратного вызова, функция, которая передается в качестве параметра в другую функцию.
Расшифровка всего вышеперечисленного:
function executor( resolveFunction, rejectFunction )
executor()
— это функция, которая, по сути, является всем, что составляет этот экземпляр промиса. Блок кода внутри обычно содержит асинхронные действия, такие как запрос на выборку. Именно внутри этого блока будет определяться, будет ли вызыватьсяresolveFunction()
илиrejectFunction()
.
resolveFunction(value);
resolveFunction()
предопределен JavaScript. Это функция обратного вызова, которая вызывается после успешного завершения блока кода запроса. Его вызов использует параметрvalue
.resolveFunction
часто сокращается доresolve
, а его параметр,value
, часто переименовывается в зависимости от особенностей самого значения. Если значениеvalue
относится к объекту человека, его можно назватьperson
.
rejectFunction(error);
rejectFunction()
также является функцией обратного вызова, предопределенной JavaScript. Если возникает ошибка, она вызывается. Параметрerror
обычно не меняется, поскольку его цель — передать ошибку.
Когда вызывается resolveFunction() or rejectFunction()
?
Чтобы ответить на этот вопрос, Обещание должно быть расширено.
let myPromise = new Promise( function executor( resolveFunction, rejectFunction) { let asyncResponse = false; // Here is where an async request code block is added. // asyncRequest() => { // return response = true; // } if (response === true) { resolveFunction( value ); } if (response === false) { rejectFunction( error ); } })
Внутри executor()
добавлено:
- Переменная
asyncResponse
имеет значение false.
•asyncResponse
представляет возвращаемое значение асинхронного запроса. - Функции
resolveFunction()
иrejectFunction()
заключены в оператор if/else. value
иerror
параметры.
Как только asyncRequest()
завершает свое действие, resolveFunction()
и rejectFunction()
вызываются на основе условий внутри блока кода. Условия зависят от функциональности, необходимой для приложения. Параметры value
и error
обычно являются объектами, полученными в результате асинхронного запроса. Эти объекты передаются в качестве параметров resolveFunction()
и rejectFunction()
, как вы видите выше.
.тогда что?
После того, как промис создан, его целью является уменьшение сложности нескольких функций обратного вызова. Она известна как «обратная пирамида гибели». Я этого не придумал. Чтобы уменьшить сложность, операторы .then()
создаются как обработчик Promise для возврата окончательного значения.
Вот как используется оператор .then()
:
let myPromise = new Promise( function executor( resolveFunction, rejectFunction) { let asyncResponse = false; // Here is where an async request code block is added. // asyncRequest() => { // return response = true; // } if (response === true) { resolveFunction(value); } if (response === false) { rejectFunction(error); } }) myPromise.then( resolveFunc(value){}, rejectFunc(error){} )
.then()
также использует собственный набор функций обратного вызова для разрешения и отклонения. Эти функции отделены от функций разрешения и отклонения обещания. Однако value
и error
являются одними и теми же значениями. Основываясь на состоянии Promises, оператор .then()
знает, какой обратный вызов использовать.
Чтобы проиллюстрировать функциональность Promise, протестируйте этот код, вставив его в консоль браузера:
const successPromise = new Promise((resolve, reject) => { // Normally there is an asyncRequest that would return an asyncResponse. // Hardcoding for example purposes. let asyncResponse = "success"; if (asyncResponse === "success") { resolve('I got this!'); } else { reject(Error('Epic Fail')); } }); console.log(successPromise .then( (value) => console.log(value), (error) => alert(error) ) );
Прогулка по коду:
- Создал объект Promise с предоставленными функциями
resolve
иreject
функций. asyncResponse
— это переменная для имитации возврата asyncRequest. Например, он жестко запрограммирован.- Оператор if/else используется для определения того, будет ли вызываться функция разрешения или отклонения.
- Поскольку ответ жестко запрограммирован, функция разрешения вызывается со значением «Я получил это!».
- «Я получил это!» это
value
, которое передается в оператор.then()
. - Поскольку состояние промиса «выполнено», вызывается функция разрешения оператора
.then()
иvalue
или «Я получил это! находится в console.logged.
Попробуйте протестировать отклоненный промис, также вставив его в консоль браузера.
const failurePromise = new Promise((resolve, reject) => { // Normally there is an asyncRequest that would return an asyncResponse. // Hardcoding for example purposes. let asyncResponse = "failure"; if (asyncResponse === "Success") { resolve("Success!"); } else { reject(Error("Epic Fail")); } }); console.log(failurePromise .then( (value) => console.log(value), (error) => alert(error) ) );
Промисов много, что работает под капотом и сбивает с толку мастера. Я надеюсь, что это объяснение и пример помогут прояснить функциональность. Протестируйте и посмотрите.