minor
This commit is contained in:
parent
9f9809004d
commit
c3783a7330
1 changed files with 8 additions and 10 deletions
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
Promisification -- is a long word for a simple transform. It's conversion of a function that accepts a callback into a function returning a promise.
|
Promisification -- is a long word for a simple transform. It's conversion of a function that accepts a callback into a function returning a promise.
|
||||||
|
|
||||||
To be more precise, we create a wrapper-function that does the same, internally calling the original one, but returns a promise.
|
|
||||||
|
|
||||||
Such transforms are often needed in real-life, as many functions and libraries are callback-based. But promises are more convenient. So it makes sense to promisify those.
|
Such transforms are often needed in real-life, as many functions and libraries are callback-based. But promises are more convenient. So it makes sense to promisify those.
|
||||||
|
|
||||||
For instance, we have `loadScript(src, callback)` from the chapter <info:callbacks>.
|
For instance, we have `loadScript(src, callback)` from the chapter <info:callbacks>.
|
||||||
|
@ -23,7 +21,7 @@ function loadScript(src, callback) {
|
||||||
// loadScript('path/script.js', (err, script) => {...})
|
// loadScript('path/script.js', (err, script) => {...})
|
||||||
```
|
```
|
||||||
|
|
||||||
Let's promisify it. The new `loadScriptPromise(src)` function will do the same, but accept only `src` (no callback) and return a promise.
|
Let's promisify it. The new `loadScriptPromise(src)` function will do the same, but accept only `src` (no `callback`) and return a promise.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let loadScriptPromise = function(src) {
|
let loadScriptPromise = function(src) {
|
||||||
|
@ -39,13 +37,13 @@ let loadScriptPromise = function(src) {
|
||||||
// loadScriptPromise('path/script.js').then(...)
|
// loadScriptPromise('path/script.js').then(...)
|
||||||
```
|
```
|
||||||
|
|
||||||
Now `loadScriptPromise` fits well in our promise-based code.
|
Now `loadScriptPromise` fits well in promise-based code.
|
||||||
|
|
||||||
As we can see, it delegates all the work to the original `loadScript`, providing its own callback that translates to promise `resolve/reject`.
|
As we can see, it delegates all the work to the original `loadScript`, providing its own callback that translates to promise `resolve/reject`.
|
||||||
|
|
||||||
As we may need to promisify many functions, it makes sense to use a helper.
|
In practice we'll probably need to promisify many functions, it makes sense to use a helper.
|
||||||
|
|
||||||
That's actually very simple -- `promisify(f)` below takes a to-promisify function `f` and returns a wrapper function.
|
We'll call it `promisify(f)`: it accepts a to-promisify function `f` and returns a wrapper function.
|
||||||
|
|
||||||
That wrapper does the same as in the code above: returns a promise and passes the call to the original `f`, tracking the result in a custom callback:
|
That wrapper does the same as in the code above: returns a promise and passes the call to the original `f`, tracking the result in a custom callback:
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ function promisify(f) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push(callback); // append our custom callback to the end of arguments
|
args.push(callback); // append our custom callback to the end of f arguments
|
||||||
|
|
||||||
f.call(this, ...args); // call the original function
|
f.call(this, ...args); // call the original function
|
||||||
});
|
});
|
||||||
|
@ -75,9 +73,9 @@ loadScriptPromise(...).then(...);
|
||||||
|
|
||||||
Here we assume that the original function expects a callback with two arguments `(err, result)`. That's what we encounter most often. Then our custom callback is in exactly the right format, and `promisify` works great for such a case.
|
Here we assume that the original function expects a callback with two arguments `(err, result)`. That's what we encounter most often. Then our custom callback is in exactly the right format, and `promisify` works great for such a case.
|
||||||
|
|
||||||
But what if the original `f` expects a callback with more arguments `callback(err, res1, res2)`?
|
But what if the original `f` expects a callback with more arguments `callback(err, res1, res2, ...)`?
|
||||||
|
|
||||||
Here's a modification of `promisify` that returns an array of multiple callback results:
|
Here's a more advanced version of `promisify`: if called as `promisify(f, true)`, the promise result will be an array of callback results `[res1, res2, ...]`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// promisify(f, true) to get array of results
|
// promisify(f, true) to get array of results
|
||||||
|
@ -105,7 +103,7 @@ f = promisify(f, true);
|
||||||
f(...).then(arrayOfResults => ..., err => ...)
|
f(...).then(arrayOfResults => ..., err => ...)
|
||||||
```
|
```
|
||||||
|
|
||||||
In some cases, `err` may be absent at all: `callback(result)`, or there's something exotic in the callback format, then we can promisify such functions without using the helper, manually.
|
For more exotic callback formats, like those without `err` at all: `callback(result)`, we can promisify such functions without using the helper, manually.
|
||||||
|
|
||||||
There are also modules with a bit more flexible promisification functions, e.g. [es6-promisify](https://github.com/digitaldesignlabs/es6-promisify). In Node.js, there's a built-in `util.promisify` function for that.
|
There are also modules with a bit more flexible promisification functions, e.g. [es6-promisify](https://github.com/digitaldesignlabs/es6-promisify). In Node.js, there's a built-in `util.promisify` function for that.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue