# 03. Promise Creation

Создать `Promise` можно одним из нескольких способов:

* При помощи конструктора `new Promise(executor)`;
* Создать Promise с одним из установленных значений:
  * `Promise.resolve()`;
  * `Promise.reject()`.
* Получить Promise вызвав одну из асинхронных операций, возвращающих Promise;
* Конвертировать вызов функции с callback в функционально идентичный Promise.

## `new Promise(...)` constructor

Promise-ы создаются при помощи конструктора `new Promise(...)`:

```javascript
new Promise(executor);
new Promise(function(resolve, reject) { ... });
```

Example:

```javascript
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)`.

Например:

```javascript
const promise = new Promise((resolve, reject) => { // (A)
    ···
    if (···) {
        resolve(value); // success
    } else {
        reject(reason); // failure
    }
});
```

После вызова resolve/reject Promise переходит в одно из установленных состояний – с результатом (resolve), или ошибкой (reject):

```javascript
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:

```javascript
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(...))`:

```javascript
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 будет когда-нибудь собран сборщиком мусора.&#x20;

## Settled Promise

Создать Promise c определенным состоянием можно при помощи одного из следующих методов:

* `Promise.resolve(value|promise|thenable)` - создает Promise с состоянием `fulfilled` и с установленным значением.
* `Promise.reject(value|promise|thenable)` - создает Promise с состоянием `rejected` и с установленным значением.

```javascript
// 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`

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.

```javascript
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:

```javascript
Promise.resolve().then(function() {
  if (somethingIsNotRight()) {
    throw new Error("I will be rejected asynchronously!");
  } else {
    return "This string will be resolved asynchronously!";
  }
});
```

## `util.promisify()`

Node 8 has a new utility function: `util.promisify()`. It converts a callback-based function to a Promise-based one.

```javascript
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);
  });
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://strctr.gitbook.io/programming/01-languages/javascript/01-language/e-controls/e4-promises/03-promise-creation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
