Example usage:
Template.xyz.value = function () {
return ReactiveAsync("Template_xyz_value", function (w) {
someAsyncFunction(function (result) {
w.set(result);
w.done();
});
}, {initial: ""});
};
Package.describe({ | |
summary: "Reactive async pattern helper" | |
}); | |
Package.on_use(function (api) { | |
api.use([ | |
"deps", | |
"underscore" | |
], "client"); | |
api.add_files([ | |
"reactive-async.js" | |
], "client"); | |
api.export("ReactiveAsync"); | |
}); |
var store = {}; | |
ReactiveAsync = function (uniqueId, workspace, options) { | |
uniqueId = uniqueId + (Deps.currentComputation && Deps.currentComputation._id); | |
var opts = _.extend({ | |
initial: undefined | |
}, options); | |
if (!_.has(store, uniqueId)) { | |
store[uniqueId] = { | |
dep: new Deps.Dependency, | |
state: "idle", | |
val: opts.initial, | |
newVal: opts.initial | |
}; | |
} | |
var o = store[uniqueId]; | |
o.dep.depend(); | |
if (o.state === "idle") { | |
o.state = "working"; | |
o.newVal = opts.initial; | |
_.isFunction(workspace) && workspace({ | |
done: function () { | |
o.state = "done"; | |
this.flush(); | |
}, | |
get: function () { | |
return o.newVal; | |
}, | |
set: function (setVal) { | |
o.newVal = setVal; | |
}, | |
getCurrent: function () { | |
return o.val; | |
}, | |
flush: function () { | |
o.val = o.newVal; | |
o.dep.changed(); | |
} | |
}); | |
} | |
if (o.state === "done") { | |
o.state = "idle"; | |
} | |
return o.val; | |
}; |