You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.9 KiB
94 lines
2.9 KiB
const npm = {
|
|
stat: require('./static')
|
|
};
|
|
|
|
module.exports = function ($p) {
|
|
|
|
const exp = {
|
|
formatError: npm.stat.formatError,
|
|
isPromise: npm.stat.isPromise,
|
|
isReadableStream: npm.stat.isReadableStream,
|
|
messageGap: npm.stat.messageGap,
|
|
extend: npm.stat.extend,
|
|
resolve: resolve,
|
|
wrap: wrap
|
|
};
|
|
|
|
return exp;
|
|
|
|
//////////////////////////////////////////
|
|
// Checks if the function is a generator,
|
|
// and if so - wraps it up into a promise;
|
|
function wrap(func) {
|
|
if (typeof func === 'function') {
|
|
if (func.constructor.name === 'GeneratorFunction') {
|
|
return asyncAdapter(func);
|
|
}
|
|
return func;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
// Resolves a mixed value into the actual value,
|
|
// consistent with the way mixed values are defined:
|
|
// https://github.com/vitaly-t/spex/wiki/Mixed-Values
|
|
function resolve(value, params, onSuccess, onError) {
|
|
|
|
const self = this;
|
|
let delayed = false;
|
|
|
|
function loop() {
|
|
while (typeof value === 'function') {
|
|
if (value.constructor.name === 'GeneratorFunction') {
|
|
value = asyncAdapter(value);
|
|
}
|
|
try {
|
|
value = params ? value.apply(self, params) : value.call(self);
|
|
} catch (e) {
|
|
onError(e, false); // false means 'threw an error'
|
|
return;
|
|
}
|
|
}
|
|
if (exp.isPromise(value)) {
|
|
value
|
|
.then(data => {
|
|
delayed = true;
|
|
value = data;
|
|
loop();
|
|
return null; // this dummy return is just to prevent Bluebird warnings;
|
|
})
|
|
.catch(error => {
|
|
onError(error, true); // true means 'rejected'
|
|
});
|
|
} else {
|
|
onSuccess(value, delayed);
|
|
}
|
|
}
|
|
|
|
loop();
|
|
}
|
|
|
|
// Generator-to-Promise adapter;
|
|
// Based on: https://www.promisejs.org/generators/#both
|
|
function asyncAdapter(generator) {
|
|
return function () {
|
|
const g = generator.apply(this, arguments);
|
|
|
|
function handle(result) {
|
|
if (result.done) {
|
|
return $p.resolve(result.value);
|
|
}
|
|
return $p.resolve(result.value)
|
|
.then(res => {
|
|
return handle(g.next(res));
|
|
}, err => {
|
|
return handle(g.throw(err));
|
|
});
|
|
}
|
|
|
|
return handle(g.next());
|
|
};
|
|
}
|
|
|
|
};
|
|
|