https://github.com/boweihan/callbackpreserver
Utility class that preserves JavaScript callbacks to support multiple invocation - built on top of ES6 generators with TypeScript.
https://github.com/boweihan/callbackpreserver
callbacks es6 generators javascript js microsoft-excel microsoft-javascript-api microsoft-js-api npm-package refactoring refactoring-tools typescript
Last synced: 24 days ago
JSON representation
Utility class that preserves JavaScript callbacks to support multiple invocation - built on top of ES6 generators with TypeScript.
- Host: GitHub
- URL: https://github.com/boweihan/callbackpreserver
- Owner: boweihan
- Created: 2019-02-02T16:13:24.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-02-09T20:23:56.000Z (over 7 years ago)
- Last Synced: 2024-04-26T14:01:10.608Z (about 2 years ago)
- Topics: callbacks, es6, generators, javascript, js, microsoft-excel, microsoft-javascript-api, microsoft-js-api, npm-package, refactoring, refactoring-tools, typescript
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/callbackpreserver
- Size: 614 KB
- Stars: 1
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# CallbackPreserver

A utility class for preserving JavaScript callback function context so that the same callback can be invoked multiple times.
### Installation
`npm install --save callbackpreserver`
### Usage
1. Instantiate CallbackPreserver.
```
import CallbackPreserver from 'callbackpreserver';
const preserver = new CallbackPreserver();
```
2. Use CallbackPreserver -> preserve() in place of a callback function to hold callback context for later.
```
const methodThatAcceptsCallback = (callback) => {
const context = "temporary context";
callback(context);
}
methodThatAcceptsCallback(preserver.preserve);
```
3. Use CallbackPreserver -> run() to invoke the preserved original callback on demand.
```
// invoke preserved callback
preserver.run((context) => {
console.log(context); // "temporary context"
});
// invoke preserved callback again - idempotence
preserver.run((context) => {
console.log(context); // "temporary context"
});
```
### Use-Cases
CallbackPreserver provides a simple mechanism for code cleanliness. However, this pattern shines when used in conjuction with certain APIs that require batched context-aware callbacks. An example of this is Microsoft's `Excel.run` API used by O365 Addins to interact with Excel documents - https://docs.microsoft.com/en-us/office/dev/add-ins/excel/excel-add-ins-core-concepts.
Typical usage of `Excel.run`:
```
Excel.run(function (context) {
// load the selected range
const selectedRange = context.workbook.getSelectedRange();
selectedRange.load('address');
context.sync()
.then(function () {
console.log('The selected range is: ' + selectedRange.address);
});
// load sheet names
var sheets = context.workbook.worksheets;
sheets.load("items/name");
return context.sync()
.then(function () {
for (var i in sheets.items) {
console.log(sheets.items[i].name);
}
});
})
```
In the above example, the callback accepted by `Excel.run` is invoked with a proxy context object which is run asynchronously as a batch of operations. This makes it difficult to run your own JavaScript alongside Excel operations. This is where CallbackPreserver can come in.
```
const preserver = new CallbackPreserver();
Excel.run(preserver.preserve);
await preserver.run((context) => // perform Excel action)
// run your own code
await preserver.run((context) => // perform Excel action)
// run your own code
preserver.close() // allow context to be garbage collected
```
With CallbackPreserver the context can be reused across multiple invocations. In this example Excel operations that share a context can be pushed one at a time instead of in a batch.
### API Interface
```
interface ICallbackPreserver {
preserve: (...args: any[]) => void;
close: () => void;
run: (
callable: (...args: any[]) => Promise,
) => Promise | Promise;
}
```
### Notes
CallbackPreserver is an experimental code cleanup mechanism that utilizes ES6 generators under the hood. Use at your own risk!