Skip to content
Merged
145 changes: 144 additions & 1 deletion concepts/promises/about.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,146 @@
# About

TODO: add information on promises concept
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason.

A Promise is in one of these states:

- **pending**: initial state, neither fulfilled nor rejected.
- **fulfilled**: meaning that the operation was completed successfully and the result is available.
- **rejected**: meaning that the operation failed.

When either of these options happens, the associated handlers queued up by a promise's `then` method is called. If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached.

Example:

```javascript
const myPromise = new Promise(function (resolve, reject) {
setTimeout(function (resolve, reject) {
resolve('Jack');
}, 300);
});
myPromise.then(function (e) {
console.log(e); // expected output 'Jack'
});
```

## Instance Methods of a Promise

### then

> The `.then()` method takes up to two arguments; the first argument is a callback function for the resolved case of the promise, and the second argument is a callback function for the rejected case. Each `.then()` returns a newly generated promise object, which can optionally be used for chaining.[^1]

```javascript
const promise1 = new Promise(function (resolve, reject) {
resolve('Success!');
});
promise1.then(function (value) {
console.log(value);
// expected output: "Success!"
});
```

### catch

> A `.catch()` is really just a `.then()` without a slot for a callback function for the case when the promise is resolved. It is used to handle rejected promises.[^2]

```javascript
const promise1 = new Promise((resolve, reject) => {
throw 'An error occured';
});
promise1.catch(function (error) {
console.error(error);
});
// expected output: An error occured
```

### finally

> When the promise is settled, i.e either fulfilled or rejected, the specified callback function is executed. This provides a way for code to be run whether the promise was fulfilled successfully or rejected once the Promise has been dealt with.[^3]

```javascript
function findDataById(id) {
return new Promise(function (resolve, reject) {
let sampleData = [1, 2, 3, 4, 5];
if (sampleData[id]) {
resolve(sampleData[id]);
} else {
reject(new Error('Invalid id'));
}
});
}
findDataById(4)
.then(function (response) {
console.log(response);
})
.catch(function (err) {
console.error(err);
})
.finally(function () {
console.log('Promise completed');
});
```

## Static Methods of the Promise Class

Some of the [staic methods][promise-static-methods] that are available on `Promise` can be used resolve and reject promises. Here are a few of them:

### Promise.all

> The `Promise.all()` method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error.[^4]

```javascript
var p1 = Promise.resolve(10);
var p2 = 45;
var p3 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('Jill');
}, 300);
});
Promise.all([p1, p2, p3]).then(function (values) {
console.log(values); // => [10, 45, "Jill"]
});
```

### Promise.reject

> The `Promise.reject()` method returns a Promise object that is rejected with a given reason.[^5]

```javascript
Promise.reject(new Error('failed')).then(
function () {
// not called
},
function (error) {
console.error(error); // error in the console
}
);
```

### Promise.resolve

> The `Promise.resolve()` method returns a Promise object that is resolved with a given value. If the value is a promise, that promise is returned; if the value is a thenable (i.e. has a "then" method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.[^6]

```javascript
Promise.resolve('resolved!').then(
function (value) {
console.log(value); // "resolved!"
},
function (value) {
// not called
}
);
```

---

[^4]: `all`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
[^5]: `reject`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject
[^6]: `resolve`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve
[^1]: `then`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[^2]: `catch`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[^3]: `finally`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

[promise-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[promise-then]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[promise-finally]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
[promise-static-methods]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#static_methods
102 changes: 101 additions & 1 deletion concepts/promises/introduction.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,104 @@
# Introduction
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content of this file also needs to be copied to the introduction.md file of the translation service exercise: https://github.com/exercism/javascript/blob/main/exercises/concept/translation-service/.docs/introduction.md


The `Promise` object represents the eventual completion (or failure) of an
The [`Promise`][promise-docs] object represents the eventual completion (or failure) of an
asynchronous operation, and its resulting value.

The methods [`promise.then()`][promise-then], [`promise.catch()`][promise-catch], and [`promise.finally()`][promise-finally] are used to associate further action with a promise that becomes settled.

For example:

```javascript
const myPromise = new Promise(function (resolve, reject) {
let sampleData = [2, 4, 6, 8];
let randomNumber = Math.ceil(Math.random() * 5);
if (sampleData[randomNumber]) {
resolve(sampleData[randomNumber]);
} else {
reject('An error occured!');
}
});

myPromise
.then(function (e) {
console.log(e);
})
.catch(function (error) {
throw new Error(error);
})
.finally(function () {
console.log('Promise completed');
});
```

## Methods

These methods are available on `Promise.prototype`

**then**

> The `.then()` method takes up to two arguments; the first argument is a callback function for the resolved case of the promise, and the second argument is a callback function for the rejected case. Each `.then()` returns a newly generated promise object, which can optionally be used for chaining.[^1]

```javascript
const promise1 = new Promise(function (resolve, reject) {
resolve('Success!');
});

promise1.then(function (value) {
console.log(value);
// expected output: "Success!"
});
```

**catch**

> A `.catch()` is really just a `.then()` without a slot for a callback function for the case when the promise is resolved. It is used to handle rejected promises.[^2]

```javascript
const promise1 = new Promise((resolve, reject) => {
throw 'An error occured';
});

promise1.catch(function (error) {
console.error(error);
});
// expected output: An error occured
```

**finally**

> When the promise is settled, i.e either fulfilled or rejected, the specified callback function is executed. This provides a way for code to be run whether the promise was fulfilled successfully or rejected once the Promise has been dealt with.[^3]

```javascript
function findDataById(id) {
return new Promise(function (resolve, reject) {
let sampleData = [1, 2, 3, 4, 5];
if (sampleData[id]) {
resolve(sampleData[id]);
} else {
reject(new Error('Invalid id'));
}
});
}

findDataById(4)
.then(function (response) {
console.log(response);
})
.catch(function (err) {
console.error(err);
})
.finally(function () {
console.log('Promise completed');
});
```

---

[^1]: `then`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[^2]: `catch`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[^3]: `finally`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

[promise-docs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[promise-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[promise-then]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[promise-finally]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
4 changes: 4 additions & 0 deletions concepts/promises/links.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises",
"description": "MDN: Using promises"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise",
"description": "MDN: Introduction to Promises"
}
]
109 changes: 88 additions & 21 deletions exercises/concept/translation-service/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,104 @@
# Introduction

The [`Promise` object][mdn-promise] represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
The [`Promise`][promise-docs] object represents the eventual completion (or failure) of an
asynchronous operation, and its resulting value.

> Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.
The methods [`promise.then()`][promise-then], [`promise.catch()`][promise-catch], and [`promise.finally()`][promise-finally] are used to associate further action with a promise that becomes settled.

A `Promise` has three states:
For example:

1. unresolved
2. resolved
3. rejected
```javascript
const myPromise = new Promise(function (resolve, reject) {
let sampleData = [2, 4, 6, 8];
let randomNumber = Math.ceil(Math.random() * 5);
if (sampleData[randomNumber]) {
resolve(sampleData[randomNumber]);
} else {
reject('An error occured!');
}
});

When a `Promise` is _settled_, it means that it has either _resolved_ or _rejected_.
myPromise
.then(function (e) {
console.log(e);
})
.catch(function (error) {
throw new Error(error);
})
.finally(function () {
console.log('Promise completed');
});
```

## Guarantees
## Methods

Unlike old-fashioned _passed-in_ callbacks, a promise comes with some guarantees, including, but not limited to:
These methods are available on `Promise.prototype`

- A `Promise` can only change its state _once_, which means that a resolved promise can never become rejected.
- Callbacks added with [`.then`][mdn-promise-then] are called even if the promise has already settled.
- Multiple callback may be added using [`.then`][mdn-promise-then], and those callbacks will be invoked in the order as they were inserted.
**then**

## Chaining
> The `.then()` method takes up to two arguments; the first argument is a callback function for the resolved case of the promise, and the second argument is a callback function for the rejected case. Each `.then()` returns a newly generated promise object, which can optionally be used for chaining.[^1]

> TODO: `.then`, `.catch`
```javascript
const promise1 = new Promise(function (resolve, reject) {
resolve('Success!');
});

## Constructing
promise1.then(function (value) {
console.log(value);
// expected output: "Success!"
});
```

> TODO: `Promise.resolve` `Promise.reject` `new Promise(resolve, reject)`
**catch**

## More about promises
> A `.catch()` is really just a `.then()` without a slot for a callback function for the case when the promise is resolved. It is used to handle rejected promises.[^2]

See [this guide][mdn-guide-promise] for more about using promises.
```javascript
const promise1 = new Promise((resolve, reject) => {
throw 'An error occured';
});

[mdn-promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[mdn-promise-then]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[mdn-guide-promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
promise1.catch(function (error) {
console.error(error);
});
// expected output: An error occured
```

**finally**

> When the promise is settled, i.e either fulfilled or rejected, the specified callback function is executed. This provides a way for code to be run whether the promise was fulfilled successfully or rejected once the Promise has been dealt with.[^3]

```javascript
function findDataById(id) {
return new Promise(function (resolve, reject) {
let sampleData = [1, 2, 3, 4, 5];
if (sampleData[id]) {
resolve(sampleData[id]);
} else {
reject(new Error('Invalid id'));
}
});
}

findDataById(4)
.then(function (response) {
console.log(response);
})
.catch(function (err) {
console.error(err);
})
.finally(function () {
console.log('Promise completed');
});
```

---

[^1]: `then`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[^2]: `catch`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[^3]: `finally`, MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

[promise-docs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[promise-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[promise-then]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
[promise-finally]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally