My previous post on promises explained how to create a thenable with a custom constructor signature, which is a pretty good way to implement something like:
Calling then in the above returns a vanilla promise, which is useful most of the time.
But what about custom thens? For example, then could be used to periodically check sanity. We might only want the computation to proceed if the intermediate values pass certain checks, and fail otherwise.
new Paranoid().then(check).then(F). then(check).then(G). ...
A Validating Promise
Notes on ValidatingPromise
To thread context through a chain of thens I’ve added a copyContext method. Although super.then returns an instance of ValidatingPromise, its contract with the derived class’s constructor cannot be modified. copyContext handles copying non-native promise state, in this case validator information.
wrap takes care of wrapping onFullfilled with validation logic. It only handles onFullfilled because there is no need to validate an already rejected computation.
It all comes together in then(onFulfilled, onRejected) as follows:
- Wrap onFullfilled in validation logic.
- Create a new promise using super.then.
- Copy the non-native promise state to the new promise using copyContext.
- Return the new promise
Now we need a gimmick to test this contraption. How about a simple blacklist.
Test the blacklist
$ cat validating_promise.js blacklist.js test_blacklist.js | node Found blacklisted value 13 after intermediate values 10,5,11
As expected, the computation is rejected upon encountering a blacklisted intermediate value.