Skip to content

Commit

Permalink
Added thunkify, promisify, co
Browse files Browse the repository at this point in the history
  • Loading branch information
andot committed Nov 17, 2016
1 parent ce3c35f commit 6f2b8f4
Show file tree
Hide file tree
Showing 9 changed files with 1,030 additions and 24 deletions.
2 changes: 1 addition & 1 deletion bower.json
@@ -1,7 +1,7 @@
{
"author": "Ma Bingyao <andot@hprose.com>",
"name": "hprose-html5",
"version": "2.0.23",
"version": "2.0.24",
"description": "Hprose is a High Performance Remote Object Service Engine.",
"keywords": [
"hprose",
Expand Down
8 changes: 4 additions & 4 deletions dist/hprose-html5.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/hprose-html5.min.js

Large diffs are not rendered by default.

184 changes: 176 additions & 8 deletions dist/hprose-html5.src.js
@@ -1,4 +1,4 @@
// Hprose for HTML5 v2.0.23
// Hprose for HTML5 v2.0.24
// Copyright (c) 2008-2016 http://hprose.com
// Hprose is freely distributable under the MIT license.
// For all details and documentation:
Expand Down Expand Up @@ -1097,7 +1097,7 @@
* *
* hprose Future for HTML5. *
* *
* LastModified: Oct 21, 2016 *
* LastModified: Nov 17, 2016 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
Expand Down Expand Up @@ -1142,10 +1142,6 @@
return 'function' === typeof obj.then;
}

function toPromise(obj) {
return (isFuture(obj) ? obj : value(obj));
}

function delayed(duration, value) {
var computation = (typeof value === 'function') ?
value :
Expand Down Expand Up @@ -1276,9 +1272,10 @@
}

function attempt(handler/*, arg1, arg2, ... */) {
var thisArg = (function() { return this; })();
var args = Array.slice(arguments, 1);
return all(args).then(function(args) {
return handler.apply(undefined, args);
return handler.apply(thisArg, args);
});
}

Expand All @@ -1289,39 +1286,200 @@
});
}

function isGenerator(obj) {
return 'function' == typeof obj.next && 'function' == typeof obj['throw'];
}

function isGeneratorFunction(obj) {
if (!obj) {
return false;
}
var constructor = obj.constructor;
if (!constructor) {
return false;
}
if ('GeneratorFunction' === constructor.name ||
'GeneratorFunction' === constructor.displayName) {
return true;
}
return isGenerator(constructor.prototype);
}

function thunkToPromise(fn) {
var thisArg = (function() { return this; })();
var future = new Future();
fn.call(thisArg, function(err, res) {
if (arguments.length < 2) {
if (err instanceof Error) {
return future.reject(err);
}
return future.resolve(err);
}
if (err) {
return future.reject(err);
}
if (arguments.length > 2) {
res = Array.slice(arguments, 1);
}
future.resolve(res);
});
return future;
}

function thunkify(fn) {
return function() {
var args = Array.slice(arguments, 0);
var thisArg = this;
var results = new Future();
args.push(function() {
thisArg = this;
results.resolve(arguments);
});
try {
fn.apply(this, args);
}
catch (err) {
results.resolve([err]);
}
return function(done) {
results.then(function(results) {
done.apply(thisArg, results);
});
};
};
}

function promisify(fn) {
return function() {
var args = Array.slice(arguments, 0);
var results = new Future();
args.push(function(err, res) {
if (arguments.length < 2) {
if (err instanceof Error) {
return results.reject(err);
}
return results.resolve(err);
}
if (err) {
return results.reject(err);
}
if (arguments.length > 2) {
res = Array.slice(arguments, 1);
}
results.resolve(res);
});
try {
fn.apply(this, args);
}
catch (err) {
results.reject(err);
}
return results;
};
}

function toPromise(obj) {
if (!obj) {
return value(obj);
}
if (isPromise(obj)) {
return obj;
}
if (isGeneratorFunction(obj) || isGenerator(obj)) {
return co(obj);
}
if ('function' == typeof obj) {
return thunkToPromise(obj);
}
return value(obj);
}

function co(gen) {
var thisArg = (function() { return this; })();
if (typeof gen === 'function') {
var args = Array.slice(arguments, 1);
gen = gen.apply(thisArg, args);
}
var future = new Future();

function onFulfilled(res) {
try {
next(gen.next(res));
}
catch (e) {
future.reject(e);
}
}

function onRejected(err) {
try {
next(gen['throw'](err));
}
catch (e) {
return future.reject(e);
}
}

function next(ret) {
if (ret.done) {
future.resolve(ret.value);
}
else {
toPromise(ret.value).then(onFulfilled, onRejected);
}
}

if (!gen || typeof gen.next !== 'function') {
return future.resolve(gen);
}
onFulfilled();

return future;
}

function wrap(handler, thisArg) {
return function() {
thisArg = thisArg || this;
return all(arguments).then(function(args) {
return handler.apply(thisArg, args);
var result = handler.apply(thisArg, args);
if (isGeneratorFunction(result)) {
return co.call(thisArg, result);
}
return result;
});
};
}

function forEach(array, callback, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.forEach(callback, thisArg);
});
}

function every(array, callback, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.every(callback, thisArg);
});
}

function some(array, callback, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.some(callback, thisArg);
});
}

function filter(array, callback, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.filter(callback, thisArg);
});
}

function map(array, callback, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.map(callback, thisArg);
});
Expand Down Expand Up @@ -1396,12 +1554,14 @@
}

function find(array, predicate, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.find(predicate, thisArg);
});
}

function findIndex(array, predicate, thisArg) {
thisArg = thisArg || (function() { return this; })();
return all(array).then(function(array) {
return array.findIndex(predicate, thisArg);
});
Expand All @@ -1428,6 +1588,9 @@
settle: { value: settle },
attempt: { value: attempt },
run: { value: run },
thunkify: { value: thunkify },
promisify: { value: promisify },
co: { value: co },
wrap: { value: wrap },
// for array
forEach: { value: forEach },
Expand Down Expand Up @@ -1735,6 +1898,11 @@

global.hprose.Future = Future;

global.hprose.thunkify = thunkify;
global.hprose.promisify = promisify;
global.hprose.co = co;
global.hprose.co.wrap = global.hprose.wrap = wrap;

function Completer() {
var future = new Future();
Object.defineProperties(this, {
Expand Down
3 changes: 2 additions & 1 deletion gulpfile.js
Expand Up @@ -41,7 +41,8 @@ gulp.task('concat', ['clear'], function() {
});

gulp.task('uglify', ['concat'], function() {
return gulp.src(['dist/hprose-html5.src.js'])
return gulp.src(['dist/hprose-html5.src.js',
'utils/regenerator-runtime.js'])
.pipe(concat('hprose-html5.js'))
.pipe(uglify())
.pipe(gulp.dest('dist'));
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,7 +1,7 @@
{
"name": "hprose-html5",
"filename": "hprose-html5.js",
"version": "2.0.23",
"version": "2.0.24",
"description": "Hprose is a High Performance Remote Object Service Engine.",
"homepage": "https://github.com/andot/hprose",
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion src/CopyRight.js
@@ -1,4 +1,4 @@
// Hprose for HTML5 v2.0.23
// Hprose for HTML5 v2.0.24
// Copyright (c) 2008-2016 http://hprose.com
// Hprose is freely distributable under the MIT license.
// For all details and documentation:
Expand Down

0 comments on commit 6f2b8f4

Please sign in to comment.