ericelliott / ericelliott/speculation

Speculation as a promise wrapper

Open
#9 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
198
Forks
6
PR merge metrics
No merged PRs in 30d

Description

I love the idea behind this project, as most projects will reach a point near completion when covering remaining edges -- cancelling a pending request due to timeout or in the event of an event source triggering some change in state where the pending request is no longer needed.

The one implication I personally have in the current setup is that I have to work a bit lower-level with resolvers and rejecters. I'd like to be able to "drop this in" a promise chain without much intervention. Currently I'd need to write some higher order behavior to achieve this desired result:

```js
function abortAfter(time) {
return promise => {
const cancel = new Promise(resolve => setTimeout(resolve, time);
return speculation((resolve, reject) => {
promise.then(resolve);
promise.catch(reject)
}, cancel)
};
}

abortAfter(100)(requestPromise)
.then(...)
.catch(...)
```

I could see this implementation exposing an additional path as somewhat of a static initializer

```js
speculation.fromPromise(promise, cancellable, onCancel)
```

Where `promise` is a promise generated from within the application domain, and `cancellable` is the promise that will resolve when the pending promise should become aborted.

### Example Implementation

I'm imagining a scenario as follows:
```js
speculation = ...

...

speculation.fromPromise = function (promise, cancel) {
return speculation((resolve, reject) => {
promise.then(resolve);
promise.catch(reject); // purposefully not chaining this to avoid catching exceptions downstream
}, cancel);
}
```

This would make it a lot easier to compose these pieces together with existing promises:

```js
function makeRequest() {
return fetch(..)
}

function abortAfter(time) {
return promise => speculation.fromPromise(
promise,
new Promise(resolve => setTimeout(resolve, time))
);
}

const withTimeout = abortAfter(30 * 1000);

withTimeout(makeRequest())
.then(..)
```

And otherwise simply:
```js
speculation.fromPromise(makeRequest(), abortAfter(30 * 1000))
.then(() => ..)
```

The question remains: **Does this belong within this project? Or would this be better composed by the dependent?**

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.