123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- 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 => handle(g.next(res)), err => handle(g.throw(err)));
- }
- return handle(g.next());
- };
- }
- };
|