makepromise
Version:
Make a Promise from a function with a callback and preserve its error stack.
188 lines (143 loc) • 5.45 kB
Markdown
# makepromise
[](https://www.npmjs.com/package/makepromise)
`makepromise` can be used to get a _Promise_ from a function with a callback. It will also make sure that the error stack starts at the line where the `makepromise` was called.
```
yarn add -E makepromise
```
## Table Of Contents
- [Table Of Contents](#table-of-contents)
- [API](#api)
* [`async makePromise(fn: function(...args, cb), args: (*[]|*))`](#async-makepromisefn-functionargs-cbargs--void)
* [`async makePromise(fn: function(...args, cb), args: (*[]|*), resolveValue: *)`](#async-makepromisefn-functionargs-cbargs-resolvevalue--void)
* [Binding Methods](#binding-methods)
- [Error Stack](#error-stack)
- [Copyright](#copyright)
## API
The package exports a default `makepromise` function.
```js
import makePromise from 'makepromise'
```
### <code>async <ins>makePromise</ins>(</code><sub><br/> `fn: function(...args, cb),`<br/> `args: (*[]|*),`<br/></sub><code>): <i>void</i></code>
Create a promise from a function which accepts a callback as the last argument, and where the callback will be called with 2 arguments: `error` and `result`. The arguments must be passed either as an array, or a single value.
The example below shows how to use `makePromise` with an array of arguments (promisified `truncate`) and a single argument (promisified `unlink`). The context of the example is 2 methods from a lib to create a temp file, and read data from a file.
```js
import { truncate, unlink, existsSync } from 'fs'
import makePromise from 'makepromise'
import { createTempFile, readFile } from './lib'
(async () => {
try {
// 0. SETUP: create a temp file.
const path = await createTempFile('hello-world')
const data = readFile(path)
console.log('Created temp file %s', path)
console.log('Exists: %s', existsSync(path))
console.log('Content: "%s"', data)
// 1. TRUNCATE to 5 characters.
await makePromise(truncate, [path, 5])
const data2 = await readFile(path)
console.log('Content: "%s"', data2)
// 2. ERASE the temp file.
await makePromise(unlink, path)
console.log('Exists: %s', existsSync(path))
} catch (err) {
console.log(err)
}
})()
```
```
Created temp file example/temp.data
Exists: true
Content: "hello-world"
Content: "hello"
Exists: false
```
### <code>async <ins>makePromise</ins>(</code><sub><br/> `fn: function(...args, cb),`<br/> `args: (*[]|*),`<br/> `resolveValue: *,`<br/></sub><code>): <i>void</i></code>
When `resolveValue` is passed as the last argument to the `makePromise` function, the returned promise will be forced to resolve with it.
```js
import { unlink } from 'fs'
import makePromise from 'makepromise'
import { createTempFile } from './lib'
(async () => {
try {
// 0. SETUP: create a temp file.
const path = await createTempFile()
// 1. UNLINK and return the path to the temp file.
const erasedPath = await makePromise(unlink, path, path)
console.log('Erased: %s', erasedPath)
} catch (err) {
console.log(err)
}
})()
```
```
Erased: example/temp.data
```
### Binding Methods
Sometimes, it is important to bind methods of instances to their contexts, otherwise they will loose access to `this`.
For example. when closing a _Writable_ stream, its `close` method must be bound to its instance.
```js
import { createWriteStream, unlink } from 'fs'
import makePromise from 'makepromise'
import { createTempFile, readFile } from './lib'
(async () => {
try {
// 0. SETUP: create a temp file.
const path = await createTempFile()
// 1. CREATE a write stream, and end it with data.
const ws = createWriteStream(path)
await makePromise(ws.end.bind(ws), 'example-data')
// 2. CHECK that data has been written.
const data = await readFile(path)
console.log('Read file: "%s"', data)
// 3. TEAR-DOWN: remove file.
await makePromise(unlink, path)
} catch (err) {
console.log(err)
}
})()
```
```
Read file: "example-data"
```
## Error Stack
This modules will make sure that errors are updated to include the stack trace of when `makePromise` was called, rather than have the Node's internal error stack or no stack at all.
```js
import { unlink } from 'fs'
import makePromise from 'makepromise'
(async () => {
try {
await makePromise(unlink, 'error-test-file')
} catch ({ stack }) {
console.log(stack)
}
})()
```
```
Error: ENOENT: no such file or directory, unlink 'error-test-file'
at /Users/anton/adc/makepromise/example/error-stack.js:6:11
at Object.<anonymous> (/Users/anton/adc/makepromise/example/error-stack.js:10:3)
at Module.p._compile (/Users/anton/adc/makepromise/node_modules/alamode/compile/depack.js:49:18)
at Object.k.(anonymous function).y._extensions.(anonymous function) [as .js] (/Users/anton/adc/makepromise/node_modules/alamode/compile/depack.js:51:7)
```
Without this functionality, the error stack would not appear.
```js
import { unlink } from 'fs'
(async () => {
try {
await new Promise((r, j) => {
unlink('error-test-file', (err) => {
if (err) return j(err)
return r()
})
})
} catch ({ stack }) {
console.log(stack)
}
})()
```
```
Error: ENOENT: no such file or directory, unlink 'error-test-file'
```
## Copyright
(c) [Art Deco][1] 2019
[1]: https://artd.eco