Что такое обещание
- Преимущества асинхронные операции выражены в потоке синхронных операций, избегая слоев вложенных функций обратного вызова
- Промисы могут решить проблему асинхронности, нельзя сказать, что промисы сами по себе асинхронны.
Особенности обещания
-
Состояние объекта от внешних воздействий.
Promise
Объект представляет асинхронную работу и имеет три состояния:pending
(в ходе выполнения),resolved
(успешно) иrejected
(не удалось) -
Как только состояние изменится, оно больше не изменится, вы можете получить этот результат в любое время..
Promise
Статус объекта меняется, всего два возможных: сpending
сталиresolved
И изpending
сталиrejected
- Внутри обещания происходит ошибка и не повлияет на выполнение внешней программы.
-
Promise
. После создания оно будет выполнено немедленно и не может быть отменено на полпути. Во-вторых, если вы не установите функцию обратного вызова,Promise
Внутренние ошибки брошены, не реагируют на улицу. В-третьих, когда вpending
Когда состояние не знает, где текущий прогресс этапа (начало или близится к завершению)
Применение
Основное использование
СоздайтеPromise
например, вы должны передать функцию в качестве параметра
new Promise(() => {});
new Promise(); // 报错
Эта функция может принимать две другие функции, предоставляемые движком JavaScript,resolve
а такжеreject
.函数作用:
-
resolve
--БудуPromise
Состояние объекта переходит изpending
сталиresolved
, передать результат асинхронной операции в качестве параметра -
reject
--БудуPromise
Состояние объекта переходит изpending
сталиrejected
Ошибки асинхронной операции могут быть в качестве параметра для передачи
let promise = new Promise((resolve, reject) => {
// do something
if (true) {
// 将参数返回,供then方法使用
resolve("value");
} else {
// 将参数返回,供then方法使用
reject("error");
}
});
Promise
После создания экземпляра вы можете использоватьthen
способы оговариваются отдельноresolved
статус иrejected
Функция обратного вызова статуса.
promise.then(
value => {
// resolved时调用,value为resolve函数返回的参数
console.log(value);
},
err => {
// rejected时调用,err为reject函数返回的参数
console.log(err);
}
);
когдаthen
Когда метод имеет только один функциональный параметр, онresolved
Состояние метода обратного вызова
promise.then(value => {
// 只有状态为resolved时才能调用,如果返回的是rejected状态,则报错 Uncaught (in promise) error
console.log(value);
});
Только когда обещание состояния разрешено или отклонено, метод будет вызываться
Промисы выполняются, как только они созданы, ипередачаresolve
илиreject
Promise
let promise = new Promise(resolve => {
console.log("Promise");
resolve();
console.log("!!!")
});
promise.then(function() {
console.log("resolved.");
});
console.log("Hi!");
// Promise
// !!!
// Hi!
// resolved
resolve
Promise
Пример
const p1 = new Promise((_, reject) => {
setTimeout(() => reject('error'), 3000);
});
const p2 = new Promise(resolve => {
setTimeout(() => resolve(p1), 1000);
});
p2.then(
result => console.log(result),
error => console.log(error) // error
);
В приведенном выше коде
p1
ЯвляетсяPromise
, через 3 секунды становитсяrejected
.p2
состояние меняется через 1 секунду,resolve
метод возвращаетp1
. из-заp2
То, что возвращается, является другим обещанием, в результате чегоp2
Собственный статус недействителен,p1
государственное решениеp2
положение дел. Итак, последнийthen
Высказывания все становятся направленными к последнему (p1
). Еще через 2 секундыp1
сталиrejected
, вызывая триггерcatch
Функция обратного вызова, указанная методом.
Вышеприведенное является исходным объяснением, мы можем понять его какp2.then
в реальностиp1.then
Внутри промиса возникает ошибка, ошибка будет отклонена
const promise = new Promise(resolve => {
throw new Error("aa") // 等同于reject(new Error("aa"))
resolve("resolve");
});
console.log(promise) // Promise {<rejected>: Error: aa ...... }
В методе, то то же самое верно
Promise.resolve()
Использование этого метода может быть любое значение в обещании
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
Promise.resolve()
Метод разделен на четыре случая параметра
Параметр является примером обещания
Если аргумент является экземпляром Promise, тоPromise.resolve
Этот экземпляр будет возвращен без изменений и без изменений. Он ведет себя как пустая оболочка.
const promise = new Promise((resolve, reject) => {
reject("resolve");
});
let p = Promise.resolve(promise);
console.log(p == promise); // true
параметр являетсяthenable
объект
thenable
Объект относится кthen
Объектный метод,Promise.resolve()
Метод превратит этот объект в объект Promise, а затем немедленно выполнит его.thenable
объектthen()
метод
// thenable对象
let thenable = {
then(resolve, reject) {
reject(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(value => {
console.log("resolved",value);
},err => {
console.log("rejected",err); // 42
});
В приведенном выше кодеthenable
объектthen()
После выполнения метода объектp1
Государство становитсяresolved
, тем самым немедленно выполняя последнийthen()
Функция обратного вызова, указанная методом, вывод 42
параметр не имеетthen()
объект метода или вообще не объект
const p = Promise.resolve('Hello');
p.then( s => {
console.log(s) // Hello
});
без параметров
Promise.resolve()
Метод разрешено вызывать без параметров, и он напрямую возвращаетresolved
Состояние объекта обещания
Promise.resolve();
// 相当于
new Promise(resolve => resolve(undefined))
Promise.reject()
Promise.reject()
Способ также возвращает новое состояние отклонено примерами обещания
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
Любой параметр будет причиной отклонения контракта, даже не решенное обещание
let promise = Promise.resolve("foo")
let p1 = Promise.reject(promise);
p1.then(value => {
console.log("resolved",value);
},err => {
console.log("rejected",err); // Promise {<fulfilled>: 'foo'}
});
Promise.prototype.then()
then
Метод определен в объекте-прототипеPromise.prototype
Выше оба параметра метода then являются необязательными. то метод может вернуть**全新的promise实例**
Таким образом, то тогда метод может быть прикован. Что определяет возврат этого метода к обещанию?
// 未传入处理程序
const p1 = Promise.resolve("foo")
let pt1 = p1.then();
console.log(p1); // Promise <resolved>: foo
console.log(pt1); // Promise <resolved>: foo
// 未成功调用then方法
const p2 = Promise.reject("bar")
let pt2 = p2.then(value => {
console.log(value);
});
- использовать
Promise.resolve()
обертывание возвращаемого значения
Возвращаемое значение по умолчаниюundefined
let pt3 = p2.then(undefined, value => {
console.log(value);
});
console.log(pt3);
Promise.prototype.catch()
catch()
путь.then(null, rejection)
или.then(undefined, rejection)
Псевдоним для указания функции обратного вызова при возникновении ошибки.catch()
Метод также возвращает объект Promise (такой же, как метод then)
const promise = new Promise((_, reject) => {
reject("reject");
});
promise
.then(value => {
console.log(value);
})
// 发生错误,或者reject时执行
.catch(value => {
console.log(value);
});
Если состояние Promise сталоresolved
, то выдавать ошибку недопустимо.
const promise = new Promise(resolve => {
resolve("resolve");
throw new Error("fail");
});
promise.then(value => console.log(value));
Все в обещанииОшибка не обработанаЛуковицы до последнего улова
const promise = new Promise(resolve => {
resolve("resolve");
});
promise
.then(value => {
console.log(value);
throw new Error("fail1");
})
.then(() => {
throw new Error("fail2");
})
.catch(value => {
console.log(value);
});
В приведенном выше коде catch сначала напечатает первую ошибку, а когда первая ошибка будет устранена (закомментировано все в порядке), вторая ошибка будет напечатана в catch.
Возвращаемое значение catch по-прежнему обещано, способ возврата обещания похож на then, поэтому метод then все еще можно вызывать после catch
Ошибки внутри промиса не влияют на код вне промиса
Promise.prototype.finally()
finally()
Независимо от метода, используемого для целенаправленного конечного состояния обещания, будет выполнена операция.finally
Функция обратного вызова метода не принимает никаких параметров, а это значит, чтоfinally
Операции в методе должны быть независимы от состояния и не зависеть от результата выполнения промиса.
const promise = new Promise(resolve => {
resolve("resolve");
});
promise.finally(() => {
console.log(11); // 11
});
finally
сущность
promise.finally(() => {
// do something
});
// 等同于
promise.then(
result => {
// do something
return result;
},
error => {
// do something
throw error;
}
);
finally
Возвращаемое значение — это новое обещание, похожее на исходное значение.
Promise.all()
Promise.all()
Метод для множества экземпляров обещают, упакованные в новое обещание экземпляра
const p = Promise.all([p1, p2, p3]);
Promise.all()
p1
,p2
,p3
оба экземпляра Promise, если нет, то он будет вызванPromise.resolve
方法,将参数转为 Promise 实例,再进一步处理。 Кроме того,Promise.all()
Параметры метода могут не быть массивами, но у них должен быть интерфейс итератор, и каждый возвращенный элемент - это экземпляр обещания.p
Государствомp1
,p2
,p3
Решение разделено на два случая.
- Только
p1
,p2
,p3
Государство сталоresolved
,p
государство станетresolved
,В настоящее времяp1
,p2
,p3
Возвращаемые значения образуют массив, который передается вp
функция обратного вызова. - если только
p1
,p2
,p3
один из них былrejected
,p
Государство становитсяrejected
В этом случае первымreject
Примеры возвращаемого значения будут переданы вp
функция обратного вызова.
let p2 = Promise.reject(2);
let promise = Promise.all([1, p2, 3]);
promise
.then(value => {
console.log(value);
})
.catch(err => {
console.log(err); // 2
});
console.log(promise);
Если экземпляр Promise в качестве параметра определяется сам по себеcatch
метод, то, как только онrejected
, не заводитсяPromise.all()
изcatch
метод
const p1 = new Promise(resolve => {
resolve("hello");
})
.then(result => result)
.catch(e => e);
const p2 = new Promise(() => {
throw new Error("报错了");
})
.then(result => result)
.catch(e => e); // p2实际上是catch返回的promise实例
Promise.all([p1, p2])
.then(result => console.log(result)) // ['hello', Error: 报错了]
.catch(e => console.log(e)); // 不触发
Promise.race()
Promise.race()
Этот метод также заключается в переносе нескольких экземпляров Promise в новый экземпляр Promise.Promise.race()
Параметры метода те же, что иPromise.all()
Метод тот же, если это не экземпляр промиса, сначала будет вызван следующийPromise.resolve()
метод, который преобразует параметр в экземпляр Promise для дальнейшей обработки.
const p = Promise.race([p1, p2, p3]);
В приведенном выше коде, покаp1
,p2
,p3
Один из экземпляров первым меняет состояние,p
статус меняется соответственно. Возвращаемое значение экземпляра Promise, который изменился первым, передается вp
функция обратного вызова.
Promise.allSettled()
Promise.allSettled()
Метод принимает массив экземпляров Promise в качестве параметров, заключенных в новый экземпляр Promise. Просто подождите, пока все эти экземпляры параметров вернут результаты, либоfulfilled
ещеrejected
, экземпляр оболочки завершится, и параметры будут такими же, какPromise.all()
так же
let p2 = Promise.reject(2);
let promise = Promise.allSettled([1, p2, 3]);
promise.then(value => {
console.log(value); // [{status: "fulfilled", value: 1},{status: "rejected", reason: 2},{status: "fulfilled", value: 3}]
});
console.log(promise);
Promise.allSettled()
Состояние возвращенного экземпляра обещания может стать толькоresolved
, параметр, полученный его функцией слушателя, представляет собой массив, каждый элемент массива является объектом, каждый объект имеет атрибут состояния, значением этого атрибута может быть только строкаfulfilled
или строкаrejected
.fulfilled
, объект имеетvalue
Атрибуты,rejected
Когдаreason
Атрибут, соответствующий возвращаемому значению двух состояний.
Promise.any()
Этот метод принимает набор экземпляров Promise в качестве параметров, заключает его в новый экземпляр Promise и возвращает его. Пока один из экземпляров параметра становитсяfulfilled
состояние, экземпляр оболочки становитсяfulfilled
состояние; если все экземпляры параметров становятсяrejected
состояние, экземпляр оболочки становитсяrejected
условие.Promise.any()
а такжеPromise.race()
Способ очень похож, только с одним отличием, то есть не станет из-за некого промисаrejected
статус заканчивается.
let p1 = Promise.reject(1);
let p2 = Promise.reject(2);
let promise = Promise.any([p1, p2, 3]);
promise.then(value => {
console.log(value); // 3
});
console.log(promise);
Когда все экземпляры возвращают статусrejected
час,Promise.any()
вернет состояние экземпляра, котороеrejected
let p1 = Promise.reject(1);
let p2 = Promise.reject(2);
let promise = Promise.any([p1, p2]);
promise
.then(value => {
console.log(value);
})
.catch(value => {
console.log(value); // AggregateError: All promises were rejected
});
console.log(promise);
Promise.try()
В реальной разработке часто встречается: не знаю или не хочу различать, функцииf
Это синхронная функция или асинхронная операция, но вы хотите использовать Promise для ее обработки. Потому что таким образом вы можетеf
Включать ли асинхронные операции, использовать обаthen
Метод определяет следующий шаг процесса, сcatch
метод обработкиf
Ошибка выброшена. Обычно используется следующая запись.
const f = () => console.log('now');
Promise.resolve().then(f);
console.log('next');
// next
// now
Приведенное выше обозначение имеет недостаток, т. е. еслиf
Это функция синхронизации, тогда она будет выполняться в конце события конца этого колеса.
Учитывая, что это очень распространенное требование, в настоящее времяпредложение,поставкаPromise.try
Метод заменяет вышеупомянутое письмо.
const f = () => console.log('now');
Promise.try(f);
console.log('next');
// now
// next