mirror of
https://github.com/labs42io/clean-code-typescript.git
synced 2024-11-23 13:44:04 +00:00
Concurrency
This commit is contained in:
parent
c6156ef887
commit
71dd4ba226
118
README.md
118
README.md
|
@ -12,7 +12,7 @@ Inspired from [clean-code-javascript](https://github.com/ryanmcdermott/clean-cod
|
|||
5. [Classes](#classes) *TODO*
|
||||
6. [SOLID](#solid) *TODO*
|
||||
7. [Testing](#testing) *TODO*
|
||||
8. [Concurrency](#concurrency) *TODO*
|
||||
8. [Concurrency](#concurrency)
|
||||
9. [Error Handling](#error-handling) *TODO*
|
||||
10. [Formatting](#formatting) *TODO*
|
||||
11. [Comments](#comments)
|
||||
|
@ -365,6 +365,122 @@ interface Config {
|
|||
}
|
||||
```
|
||||
|
||||
## Concurrency
|
||||
|
||||
### Prefer promises vs callbacks
|
||||
|
||||
Callbacks aren't clean, and they cause excessive amounts of nesting *(the callback hell)*.
|
||||
There are utilities that transform existing functions using the callback style to a version that returns promises
|
||||
(for Node.js see [`util.promisify`](https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original), for general purpose see [pify](https://www.npmjs.com/package/pify), [es6-promisify](https://www.npmjs.com/package/es6-promisify))
|
||||
|
||||
**Bad:**
|
||||
|
||||
```ts
|
||||
import { get } from 'request';
|
||||
import { writeFile } from 'fs';
|
||||
|
||||
function downloadPage(url: string, saveTo: string, callback: (error: Error, content?: string) => void){
|
||||
get(url, (error, response) => {
|
||||
if (error) {
|
||||
callback(error);
|
||||
} else {
|
||||
writeFile(saveTo, response.body, (error) => {
|
||||
if (error) {
|
||||
callback(error);
|
||||
} else {
|
||||
callback(null, response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
downloadPage('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', 'article.html', (error, content) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
console.log(content);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Promises supports a few patterns that could be useful in some cases:
|
||||
|Pattern|Description|
|
||||
|-------|-----------|
|
||||
|`Promise.resolve(value)`|Convert a value into a resolved promise.|
|
||||
|`Promise.reject(error)`|Convert an error into a rejected promise.|
|
||||
|`Promise.all(promises)`|Returns a new promise which is fulfilled with an array of fulfillment values for the passed promises or rejects with the reason of the first promise that rejects.|
|
||||
|`Promise.race(promises)`|Returns a new promise which is fulfilled/rejected with the result/error of the first settled promise from the array of passed promises.|
|
||||
|
||||
`Promise.all` is especially useful when there is a need to run tasks in parallel. `Promise.race` makes it easier to implement things like timeouts for promises.
|
||||
|
||||
**Good:**
|
||||
|
||||
```ts
|
||||
import { get } from 'request';
|
||||
import { writeFile } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const write = promisify(writeFile);
|
||||
|
||||
function downloadPage(url: string, saveTo: string): Promise<string> {
|
||||
return get(url)
|
||||
.then(response => write(saveTo, response))
|
||||
}
|
||||
|
||||
downloadPage('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', 'article.html')
|
||||
.then(content => console.log(content))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
### Async/Await are even cleaner than Promises
|
||||
|
||||
With async/await syntax you can write code that is far cleaner and more understandable that chained promises. Within a function prefixed with `async` keyword you have a way to tell the JavaScript runtime to pause the execution of code on the `await` keyword (when used on a promise).
|
||||
|
||||
**Bad:**
|
||||
|
||||
```ts
|
||||
import { get } from 'request';
|
||||
import { writeFile } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const write = util.promisify(writeFile);
|
||||
|
||||
function downloadPage(url: string, saveTo: string): Promise<string> {
|
||||
return get(url).then(response => write(saveTo, response))
|
||||
}
|
||||
|
||||
downloadPage('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', 'article.html')
|
||||
.then(content => console.log(content))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
|
||||
**Good:**
|
||||
|
||||
```ts
|
||||
import { get } from 'request';
|
||||
import { writeFile } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const write = promisify(writeFile);
|
||||
|
||||
async function downloadPage(url: string, saveTo: string): Promise<string> {
|
||||
const response = await get(url);
|
||||
await write(saveTo, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
// somewhere in an async function
|
||||
try {
|
||||
const content = await downloadPage('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', 'article.html');
|
||||
console.log(content);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
```
|
||||
|
||||
## Comments
|
||||
|
||||
The use of a comments is an indication of failure to express without them. Code should be the only source of truth.
|
||||
|
|
Loading…
Reference in a new issue