UNPKG

makepromise

Version:

Make a Promise from a function with a callback and preserve its error stack.

188 lines (143 loc) 5.45 kB
# makepromise [![npm version](https://badge.fury.io/js/makepromise.svg)](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/>&nbsp;&nbsp;`fn: function(...args, cb),`<br/>&nbsp;&nbsp;`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/>&nbsp;&nbsp;`fn: function(...args, cb),`<br/>&nbsp;&nbsp;`args: (*[]|*),`<br/>&nbsp;&nbsp;`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