Автор оригинала: Brandon Wozniewicz.
Что обещание?
Обещание JavaScript – это объект, который представляет собой завершение или неудачу асинхронной задачи и Это результирующее значение
Конец.
Я шучу конечно. Итак, что значит это определение даже?
Прежде всего, многие вещи в JavaScript являются объектами. Вы можете создать объект несколько разных способов. Наиболее распространенным способом является объектом буквальный синтаксис:
const myCar = {
color: 'blue',
type: 'sedan',
doors: '4',
};Вы могли бы также создать Класс и создать его с помощью Новый ключевое слово.
class Car {
constructor(color, type, doors) {
this.color = color;
this.type = type;
this.doors = doors
}
}
const myCar = new Car('blue', 'sedan', '4');console.log (mycar);
Обещание – это просто объект, который мы создаем, как более поздний пример. Мы создали это с Новый ключевое слово. Вместо трех параметров мы прошли, чтобы сделать наш автомобиль (цвет, тип и двери), мы проходим в функции, которая принимает два аргумента: решить и Отклонить Отказ
В конечном итоге, обещания рассказывают нам что-то о завершении асинхронной функции, мы вернули его из-за того, что он работал или не сделал. Мы говорим, что функция прошла успешно, сказав обещание разрешено и неудачно, сказав обещание отклоненный.
const myPromise = new Promise(function(resolve, reject) {});Console.log (MyPromise);
const myPromise = new Promise(function(resolve, reject) {
resolve(10);
});Видите, не слишком страшно – просто объект, который мы создали. И, если мы немного расширим это:
Кроме того, мы можем пропустить все, что мы хотели бы решить и отклонить. Например, мы могли бы пройти объект вместо строки:
return new Promise((resolve, reject) => {
if(somethingSuccesfulHappened) {
const successObject = {
msg: 'Success',
data,//...some data we got back
}
resolve(successObject);
} else {
const errorObject = {
msg: 'An error occured',
error, //...some error we got back
}
reject(errorObject);
}
});Или, как мы видели ранее, нам не нужно ничего проходить:
return new Promise((resolve, reject) => {
if(somethingSuccesfulHappend) {
resolve()
} else {
reject();
}
});А как насчет «асинхронной» части определения?
JavaScript – это отдельная резьба. Это означает, что он может запускать только одну вещь за раз. Если вы можете представить дорогу, вы можете подумать о JavaScript в качестве одноразового шоссе. Определенный код (асинхронный код) может сдвинуть на плечо, чтобы позволить другому коду. Когда этот асинхронный код сделан, он возвращается к проезжей части.
На вынос:
Обещания дают нам способ дождаться нашего асинхронного кода для завершения, захватить некоторые значения от него и передавайте эти значения на другие части нашей программы.
У меня есть статья здесь, что погружает более глубокие в эти концепции: Брошено для цикла: понимание петлей и тайм-аутов в JavaScript.
Как мы используем обещание?
Использование обещания также называется потребляющий Обещание. В нашем примере выше наша функция возвращает объект обещания. Это позволяет нам использовать метод цепочки с нашей функцией.
Вот пример цепочки методов, который я видела:
const a = 'Some awesome string';
const b = a.toUpperCase().replace('ST', '').toLowerCase();
console.log(b); // some awesome ringТеперь вспомните наши (притворяться) обещание:
const somethingWasSuccesful = true;
function someAsynFunction() {
return new Promise((resolve, reject){
if (somethingWasSuccesful) {
resolve();
} else {
reject()
}
});
}А также , потребляя наше обещание, используя цепочку метода:
someAsyncFunction .then(runAFunctionIfItResolved(withTheResolvedValue)) .catch(orARunAfunctionIfItRejected(withTheRejectedValue));
(Больше) реальный пример.
Представьте себе, что у вас есть функция, которая получает пользователям из базы данных. Я написал пример функции на кодепене, который имитирует API, которую вы можете использовать. Он предоставляет два варианта доступа к результатам. Один, вы можете предоставить функцию обратного вызова, где вы можете получить доступ к пользователю или любой ошибке. Или два, функция возвращает обещание как способ доступа к пользователю или ошибке.
Традиционно мы получим доступ к результатам асинхронного кода посредством использования обратных вызовов.
rr someDatabaseThing(maybeAnID, function(err, result)) {
//...Once we get back the thing from the database...
if(err) {
doSomethingWithTheError(error)
} else {
doSomethingWithResults(results);
}
}Использование обратных вызовов – Хорошо пока они не станут чрезмерно вложенными. Другими словами, вы должны запустить более асинхронный код с каждым новым результатом. Эта модель обратных вызовов в обратных вызовах может привести к чему-то известному как «обратный ад».
Обещания предлагают нам более элегантный и читаемый способ увидеть поток нашей программы.
doSomething() .then(doSomethingElse) // and if you wouldn't mind .catch(anyErrorsPlease);
Написание собственного обещания: Goldilocks, три медведя и суперкомпьютер
Представьте, что вы нашли миску супа. Вы хотели бы знать температуру этого супа, прежде чем съесть его. У вас нет термометров, но, к счастью, у вас есть доступ к суперкомпьютеру, который говорит вам температуру чаши супа. К сожалению, этот суперкомпьютер может занять до 10 секунд, чтобы получить результаты.
Вот пара вещей, чтобы заметить.
- Мы инициируем глобальную переменную под названием
РезультатОтказ - Мы смоделируем продолжительность задержки сети с помощью
Math.random ()иSetimeout ()Отказ - Мы смоделируем температуру с
Math.random ()Отказ - Мы сохраняем задержку и значения температуры, ограниченные в диапазоне, добавив дополнительную «математику». Диапазон для
Tempот 1 до 300; Диапазон длязадержкасоставляет 1000 мс до 10000 мс (от 1 до 10 секунд). - Мы регистрируем задержку и температуру, поэтому у нас есть идея того, как долго эта функция возьмет, и результаты, которые мы ожидаем, когда это будет сделано.
Запустите функцию и войдите в систему результатов.
getTemperature(); console.log(results); // undefined
Температура не определена. Что случилось?
Функция займет определенное время для запуска. Переменная не устанавливается до конца задержки. Поэтому, пока мы запускаем функцию, Сетримс асинхронный. Часть кода в Сетримс Перемещается из основного потока в зону ожидания.
У меня есть статья здесь, что погружает глубже в этот процесс: Брошено для цикла: понимание петлей и тайм-аутов в JavaScript.
Поскольку часть нашей функции, которые устанавливают переменную Результат Перемещается в холдинг, пока это не сделано, наш парсер свободен переходить на следующую строку. В нашем случае это наше console.log () Отказ На данный момент Результат все еще не определен с момента нашего Сетримс не закончился.
Так что еще мы можем попробовать? Мы могли бы бежать GetTemperature () а затем подождите 11 секунд (так как наша макс задержка – десять секунд) и Тогда Console.log Результаты.
getTemperature();
setTimeout(() => {
console.log(result);
}, 11000);
// Too Hot | Delay: 3323 | Temperature: 209 degЭто работает, но проблема с этой техникой есть, хотя в нашем примере мы знаем максимальную задержку сети, в реальном примере, в котором иногда может потребоваться больше десяти секунд. И, даже если бы мы могли гарантировать максимальную задержку в десять секунд, если результат будет готов раньше, мы тратите время.
Обещает спасение
Мы собираемся ревертировать наши GetTemperature () функция, чтобы вернуть обещание. И вместо того, чтобы установить результат, мы отклоним обещание, если результат не является «справедливым», и в этом случае мы решим обещание. В любом случае мы передам некоторые значения как для разрешения, так и отклонения.
Теперь мы можем использовать результаты нашего обещания, которые мы возвращаемся (также знаем как потребляя обещание).
getTemperature() .then(result => console.log(result)) .catch(error => console.log(error)); // Reject: Too Cold | Delay: 7880 | Temperature: 43 deg
.then будет вызван, когда наше обещание разрешится и вернет любую информацию, которую мы передаем в решить Отказ
.catch будет вызван, когда наше обещание отклоняет и вернет любую информацию, которую мы передаем в Отклонить Отказ
Скорее всего, вы будете потреблять обещания больше, чем вы создадите их. В любом случае они помогают сделать наш код более элегантным, читающимся и эффективным.
Резюме
- Обещания – это объекты, которые содержат информацию о завершении некоторого асинхронного кода и любых полученных значений, в которых мы хотим пройти.
- Чтобы вернуть обещание, которое мы используем
Вернуть новое обещание ((разрешение, отклонение) => {}) - Чтобы потреблять обещание, которое мы используем
.thenполучить информацию от обещания, которое решило, и.catchполучить информацию от обещания, которое отклонено. - Вы, вероятно, будете использовать (потреблять) обещания больше, чем вы напишите.
использованная литература
1.) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Оригинал: “https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/”