Permalink
Browse files

mock model

  • Loading branch information...
1 parent de9da7c commit 0fd77fe8a803ecedbb0b5969e31196145316fa61 @youngjay committed May 26, 2013
Showing with 623 additions and 464 deletions.
  1. +25 −0 Gruntfile.js
  2. +2 −0 build/class.min.js
  3. +2 −0 build/event.min.js
  4. +24 −1 lib/index.js
  5. +14 −12 lib/preserved-event.js
  6. +91 −25 lib/promise.js
  7. +37 −23 package.json
  8. +77 −77 test/fs.js
  9. +187 −33 test/promise.js
  10. +164 −293 test/rx.js
View
@@ -0,0 +1,25 @@
+module.exports = function(grunt) {
+
+ // Project configuration.
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+ uglify: {
+ options: {
+ banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
+ },
+ build: {
+ files: {
+ 'build/class.min.js': 'lib/class.js',
+ 'build/event.min.js': 'lib/event.js'
+ }
+ }
+ }
+ });
+
+ // Load the plugin that provides the "uglify" task.
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+
+ // Default task(s).
+ grunt.registerTask('default', ['uglify']);
+
+};
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,7 +1,10 @@
var Promise = require('./promise');
+var PreservedEvent = require('./preserved-event')
+var Event = require('./event');
module.exports = {
- Event: require('./event'),
+ Event: Event,
+ PreservedEvent: PreservedEvent,
Promise: Promise,
then: function(fn) {
@@ -10,5 +13,25 @@ module.exports = {
when: function() {
return Promise.when.apply(Promise, arguments);
+ },
+
+ any: function() {
+ return Promise.any.apply(Promise, arguments);
+ },
+
+ _drivenBy: function(dispatcher, target) {
+ var notify = dispatcher.notify;
+ target.subscribe(function() {
+ notify.apply(dispatcher, arguments);
+ });
+ return this.when(dispatcher);
+ },
+
+ preservedBy: function(subscribable) {
+ return this._drivenBy(new PreservedEvent(), subscribable);
+ },
+
+ notifiedBy: function(subscribable) {
+ return this._drivenBy(new Event(), subscribable);
}
};
View
@@ -2,17 +2,19 @@ var Event = require('./event');
var notify = Event.prototype.notify;
var subscribe = Event.prototype.subscribe;
-module.exports = Event.extend({
- notify: function() {
- this._lastArgs = arguments;
- return notify.apply(this, arguments);
- },
+module.exports = Event
+ .extend({
+ notify: function() {
+ this._lastArgs = arguments;
+ return notify.apply(this, arguments);
+ },
- subscribe: function(fn) {
- var dispose = subscribe.apply(this, arguments);
- if (this._lastArgs) {
- fn.apply(null, this._lastArgs);
+ subscribe: function(fn) {
+ var dispose = subscribe.apply(this, arguments);
+ if (this._lastArgs) {
+ fn.apply(null, this._lastArgs);
+ }
+ return dispose;
}
- return dispose;
- }
-});
+ })
+;
View
@@ -1,4 +1,3 @@
-var PreservedEvent = require('../lib/preserved-event');
var slice = [].slice;
var _ = require('underscore');
var Class = require('./class');
@@ -12,26 +11,93 @@ var PromiseInterFace = Subscribable.extend({
},
subscribe: function(subscriber) {
- return this._handle(subscriber || noop);
+ return this._handle(subscriber);
},
- then: function(transformer) {
+ thenCallback: function(transformer) {
var self = this;
return new Promise(function(subscriber) {
- return self.subscribe(function() {
- var ret = transformer.apply(null, slice.call(arguments).concat([subscriber]));
- if (ret !== undefined) {
- subscriber(ret);
+ // 在每次进入的时候,如果上次的返回值是function的话,
+ // 则认为那是一个dispose,需要调用它做一个清理
+ var subscriberDisposeHandler;
+
+ var disposePreviousSubscriber = function() {
+ if (_.isFunction(subscriberDisposeHandler)) {
+ subscriberDisposeHandler();
}
+ };
+
+ var disposeCurrentSubscriber = self.subscribe(function() {
+ disposePreviousSubscriber();
+ subscriberDisposeHandler = transformer.call(null, slice.call(arguments), subscriber);
});
+
+ return function() {
+ disposeCurrentSubscriber();
+ disposePreviousSubscriber();
+ }
});
+ },
+
+ then: function(transformer) {
+ return this.thenCallback(function(args, callback) {
+ return transformer.apply(null, args.concat(callback));
+ })
+ },
+
+ pick: function() {
+ var keys = slice.call(arguments);
+ return this.thenCallback(function(args, callback) {
+ if (args.length) {
+ callback.apply(null, args.map(function(o) {
+ return _.pick.apply(_, [o].concat(keys));
+ }))
+ } else {
+ callback();
+ }
+ });
+ },
+
+ pluck: function(key) {
+ return this.thenCallback(function(args, callback) {
+ if (args.length) {
+ callback.apply(null, _.pluck(args, key));
+ } else {
+ callback();
+ }
+ });
+ },
+
+ done: function() {
+ return this.subscribe(noop)
}
})
.mixStatic({
- when: function() {
+ when: function(singleSubscribable) {
+ // shortcut for single subscribable
+ if (arguments.length === 1 && !_.isArray(singleSubscribable)) {
+ return new Promise(function(callback) {
+ return singleSubscribable.subscribe(callback);
+ })
+ }
+
return whenAllSubscribablesAreNotified(arguments).then(function(arr, callback) {
callback.apply(null, arr);
});
+ },
+
+ any: function() {
+ var subscribables = arguments;
+ return new Promise(function(callback) {
+ var disposes = _.map(subscribables, function(subscribable) {
+ return subscribable.subscribe(callback);
+ });
+ return function() {
+ _.each(disposes, function(dispose) {
+ dispose();
+ });
+ }
+ });
}
})
@@ -42,15 +108,13 @@ var Promise = PromiseInterFace.extend(
var dispose = handle(function() {
if (!isDisposed) {
- whenAllSubscribablesAreNotified(arguments).subscribe(function(arr) {
- subscriber.apply(null, arr);
- });
+ subscriber.apply(null, arguments);
}
});
return function() {
if (!isDisposed) {
- isDisposed = true;
+ isDisposed = true;
if (_.isFunction(dispose)) {
dispose();
}
@@ -70,7 +134,7 @@ var ReturnObjectPromise = PromiseInterFace.extend(
}
);
-var containsSubscribable = function(o) {
+var containSubscribable = function(o) {
if (!o) {
return false;
}
@@ -90,21 +154,23 @@ var whenAllSubscribablesAreNotified = function(subscribables) {
subscribables = slice.call(subscribables);
- return containsSubscribable(subscribables) ? new Promise(function(callback) {
- var results = new Array(subscribables.length);
+ if (!containSubscribable(subscribables)) {
+ return new ReturnObjectPromise(subscribables);
+ }
- var check = creatCheck(results, callback);
+ return new Promise(function(callback) {
+ var results = new Array(subscribables.length);
- var disposes = checkEachSubscribables(subscribables, check);
+ var check = creatCheck(results, callback);
- return function() {
- disposes.forEach(function(dispose) {
- dispose();
- });
- }
- }) :
- new ReturnObjectPromise(subscribables);
- ;
+ var disposes = checkEachSubscribables(subscribables, check);
+
+ return function() {
+ disposes.forEach(function(dispose) {
+ dispose();
+ });
+ }
+ });
};
var creatCheck = function(results, callback) {
View
@@ -1,25 +1,39 @@
{
- "name": "rxc",
- "author": "youngjay <hiyoungjay@gmail.com>",
- "description": "a reactive program tool",
- "keywords": [
- "reactive",
- "async",
- "event"
- ],
- "repository": {
- "type": "git",
- "url": "https://github.com/youngjay/rxc.git"
- },
- "version": "0.0.2",
- "engine": "*",
- "main": "./index",
- "devDependencies": {
- "mocha": "*",
- "spec": "*",
- "sinon": "*"
- },
- "dependencies" : {
- "underscore": "*"
- }
+ "name": "rxc",
+ "author": "youngjay <hiyoungjay@gmail.com>",
+ "description": "a reactive program tool",
+ "keywords": [
+ "reactive",
+ "async",
+ "event"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/youngjay/rxc.git"
+ },
+ "version": "0.0.2",
+ "engine": "*",
+ "main": "./index",
+ "devDependencies": {
+ "mocha": "*",
+ "chai": "*",
+ "sinon-chai": "*",
+ "spec": "*",
+ "sinon": "*",
+ "grunt": "~0.4.1",
+ "grunt-contrib-uglify": "*"
+ },
+ "dependencies": {
+ "underscore": "*"
+ },
+ "gitHead": "de9da7c79e977974cf47b941f38f2675655fd3db",
+ "readmeFilename": "README.md",
+ "directories": {
+ "example": "example",
+ "test": "test"
+ },
+ "scripts": {
+ "test": "mocha"
+ },
+ "license": "BSD"
}
Oops, something went wrong.

0 comments on commit 0fd77fe

Please sign in to comment.