Skip to content

Commit

Permalink
⚡️ Implement a custom done and waterfall static method for the `S…
Browse files Browse the repository at this point in the history
…wiftPledge` class
  • Loading branch information
skerit committed Mar 23, 2024
1 parent f49ae3d commit 8aaad55
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Add some devtools functions for custom inspect formatting
* Add `Pledge#getResolvedFunction()` method, which can be passed as an old-style callback
* Fix some `Swift` methods not using the correct schedulers
* Implement a custom `done` and `waterfall` static method for the `SwiftPledge` class

## 0.9.2 (2024-02-25)

Expand Down
84 changes: 78 additions & 6 deletions lib/pledge.js
Original file line number Diff line number Diff line change
Expand Up @@ -1382,20 +1382,49 @@ var Timeout = Fn.inherits('Pledge', function TimeoutPledge(executor, timeout, me
*
* @author Jelle De Loecker <[email protected]>
* @since 0.8.15
* @version 0.8.15
* @version 0.9.3
*
* @param {Function} executor
*/
const Swift = Fn.inherits(Pledge, function SwiftPledge(executor) {
this[EXECUTOR] = executor;
this[START_EXECUTOR](false);
if (executor != null) {
this[EXECUTOR] = executor;
this[START_EXECUTOR](false);
}
});

const SwiftObject = Object.create(Bound.Function);
SwiftObject[Blast.flowPledgeClass] = Swift;
SwiftObject[Blast.asyncScheduler] = Blast.callNow;
Swift[FNC] = SwiftObject;

/**
* Handle an old-style callback for a pledge or promise
*
* @author Jelle De Loecker <[email protected]>
* @since 0.9.3
* @version 0.9.3
*/
Swift.setStatic(function done(value, callback) {

// Pass through falsy or non-object values
if (!value || typeof value != 'object') {
return callback(null, value);
}

// Pass non-thenables through
if (!value.then) {
return callback(null, value);
}

// See if we can rip the values out of Pledge instances
if (value[STATE] == RESOLVED) {
return callback(null, value[RESOLVED_VALUE]);
}

value.then(val => callback(null, val), callback);
});

/**
* Do the given tasks in parallel
*
Expand Down Expand Up @@ -1502,18 +1531,61 @@ Swift.setStatic(function execute(value) {
return value;
});

/**
* Do a single waterfall task
*
* @author Jelle De Loecker <[email protected]>
* @since 0.9.3
* @version 0.9.3
*/
const doWaterfallTask = (pledge, tasks, index, max_index, previous_value) => {

let task = tasks[index],
next_value;

if (typeof task == 'function') {
try {
next_value = task(previous_value);
} catch (err) {
return pledge.reject(err);
}
} else {
next_value = task;
}

Swift.done(next_value, (err, result) => {

if (err) {
return pledge.reject(err);
}

if (index == max_index) {
return pledge.resolve(result);
}

doWaterfallTask(pledge, tasks, index + 1, max_index, result);
});
};

/**
* Perform a swift waterfall
*
* @author Jelle De Loecker <[email protected]>
* @since 0.8.15
* @version 0.8.15
* @version 0.9.3
*
* @return {SwiftPledge|Mixed}
*/
Swift.setStatic(function waterfall(...tasks) {
let result = SwiftObject.waterfall(...tasks);
return Swift.execute(result);
let pledge = new Swift();

doWaterfallTask(pledge, tasks, 0, tasks.length - 1, null);

if (pledge[STATE] == RESOLVED) {
return pledge[RESOLVED_VALUE];
}

return pledge;
});

/**
Expand Down

0 comments on commit 8aaad55

Please sign in to comment.