03. Promise Creation
Создать Promise
можно одним из нескольких способов:
При помощи конструктора
new Promise(executor)
;Создать Promise с одним из установленных значений:
Promise.resolve()
;Promise.reject()
.
Получить Promise вызвав одну из асинхронных операций, возвращающих Promise;
Конвертировать вызов функции с callback в функционально идентичный Promise.
new Promise(...)
constructor
new Promise(...)
constructorPromise-ы создаются при помощи конструктора new Promise(...)
:
new Promise(executor);
new Promise(function(resolve, reject) { ... });
Example:
function delay(ms) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, ms); // (A)
});
}
// Using delay():
delay(5000).then(function() {
// (B)
console.log("5 seconds have passed!");
});
Executor
Передаваемый в конструктор Promise параметр называется executor
.
Executor - это функция с двумя параметрами resolve
и reject
. Первый аргумент используется для успешной установки Promise, тогда как второй для неуспешной.
Если вычисление прошло успешно, то результат посылается при помощи
resolve(value)
Если вычисление завершилось аварийно, то клиент Promise уведомляется об ошибке при помощи
reject(error)
.
Например:
const promise = new Promise((resolve, reject) => { // (A)
···
if (···) {
resolve(value); // success
} else {
reject(reason); // failure
}
});
После вызова resolve/reject Promise переходит в одно из установленных состояний – с результатом (resolve), или ошибкой (reject):
const promise = new Promise((resolve, reject) => {
// через 1 секунду готов результат: result
setTimeout(() => resolve("result"), 1000);
// через 2 секунды — reject с ошибкой, он будет проигнорирован
setTimeout(() => reject(new Error("ignored")), 2000);
});
promise.then(
result => console.log(`Fulfilled: ${result}`), // сработает
error => console.log(`Rejected: ${error}`) // не сработает
);
It’s important to note that only the first call made to either of these methods will have an impact – once a promise is settled, it’s result can’t change. The example below creates a promise that’s fulfilled in the allowed time or rejected after a generous timeout:
function resolveUnderThreeSeconds(delay) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, delay);
setTimeout(reject, 3000);
});
}
resolveUnderThreeSeconds(2000); // resolves!
resolveUnderThreeSeconds(7000); // fulfillment took so long, it was rejected.
Если внутри executor
было выброшено исключение, то это аналогично выражению reject(new Error(...))
:
const p = new Promise((resolve, reject) => {
// Same as reject(new Error("o_O"))
throw new Error("o_O");
});
p.catch(console.log); // Error: o_O
Executor выполняется синхронно вместе с созданием Promise, но любые обработчики всегда выполняются асинхронно.
Если ни reject
ни resolve
не были вызваны, то обработчики на Promise так и не сработают и Promise будет когда-нибудь собран сборщиком мусора.
Settled Promise
Создать Promise c определенным состоянием можно при помощи одного из следующих методов:
Promise.resolve(value|promise|thenable)
- создает Promise с состояниемfulfilled
и с установленным значением.Promise.reject(value|promise|thenable)
- создает Promise с состояниемrejected
и с установленным значением.
// Using the static Promise.resolve method:
Promise.resolve("Success").then(
value => console.log(value), // "Success"
value => {
// not called
}
);
// Using the Promise.reject method:
Promise.reject(new Error("fail")).then(
error => {
// not called
},
error => console.log(error) // Stacktrace,
);
Promise.resolve
Promise.resolve
The Promise.resolve(value)
method returns a Promise
object that is resolved with the given value. If the value is a thenable (i.e. has a "then" method), the returned promise will "follow" that thenable, adopting its eventual state; if the value was a promise, that object becomes the result of the call to Promise.resolve
; otherwise the returned promise will be fulfilled with the value.
const original = Promise.resolve(33);
const cast = Promise.resolve(original);
cast.then(value => {
console.log(`value: ${value}`);
});
console.log(`original === cast ? ${original === cast}`);
// original === cast ? true
// value: 33
Promise.resolve
is good for wrapping synchronous code:
Promise.resolve().then(function() {
if (somethingIsNotRight()) {
throw new Error("I will be rejected asynchronously!");
} else {
return "This string will be resolved asynchronously!";
}
});
util.promisify()
util.promisify()
Node 8 has a new utility function: util.promisify()
. It converts a callback-based function to a Promise-based one.
const { promisify } = require("util");
const fs = require("fs");
const readFileAsync = promisify(fs.readFile); // (A)
readFileAsync("package.json", { encoding: "utf8" })
.then(text => {
console.log("CONTENT:", text);
})
.catch(err => {
console.log("ERROR:", err);
});
Last updated
Was this helpful?