UNPKG

2.05 kBJavaScriptView Raw
1//
2//
3//
4
5// deferred/promises for which the callbacks are guaranteed to be
6// called synchronously. This is important if you want to control
7// which order things happen, e.g., if you wish to tell the user of
8// the promise fullfilment before any more I/O is processed.
9
10// To make things simpler these are one-shot; you can do then and
11// resolve/reject in either order, and you can chain the results, but
12// once you've used both then and resolve/reject, it's done.
13
14// If you want to 'switch' to an async (and multi-shot) promise after
15// the first handler, do something like
16//
17// var d = sync_defer.defer();
18// return when(d.promise.then(function(v) {
19// syncStuff(v); return v;
20// }));
21//
22// where `when` is the typical promise-coercion thing you get with
23// e.g., when.js.
24
25function defer() {
26
27 var me = {resolve: undefined,
28 reject: undefined,
29 promise: {then: undefined}};
30
31 me.promise.then = function(callback, errback) {
32 var d = defer();
33 me.resolve = function(value) {
34 try { d.resolve((callback) ? callback(value) : value); }
35 catch (e) { d.reject(e); }
36 };
37 me.reject = function(err) {
38 try { d.reject((errback) ? errback(err) : err); }
39 catch (e) { d.reject(e); } // problematic; we just tried this
40 };
41 me.promise.then = error;
42 return d.promise;
43 };
44
45 me.resolve = function(value) {
46 me.promise.then = function(callback, errback) {
47 var d = defer();
48 try { d.resolve((callback) ? callback(value) : value); }
49 catch (e) { d.reject(e) }
50 return d.promise;
51 };
52 me.resolve = me.reject = error;
53 };
54
55 me.reject = function(value) {
56 me.promise.then = function(callback, errback) {
57 var d = defer();
58 try { d.reject((errback) ? errback(value) : value) }
59 catch (e) { d.reject(e) }
60 return d.promise;
61 };
62 me.resolve = me.reject = error;
63 };
64
65 function error() {
66 throw new Error("Then, resolve or reject called more than once");
67 };
68
69 return me;
70}
71
72module.exports.defer = defer;