Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
rsvp.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
rsvp.js
Commits
58066429
Commit
58066429
authored
Jun 02, 2014
by
Romain Courteaud
🐙
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP monitor pattern
parent
58953a31
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
343 additions
and
3 deletions
+343
-3
lib/rsvp.js
lib/rsvp.js
+2
-1
lib/rsvp/watcher.js
lib/rsvp/watcher.js
+112
-0
test/tests/extension_test.js
test/tests/extension_test.js
+229
-2
No files found.
lib/rsvp.js
View file @
58066429
...
...
@@ -4,6 +4,7 @@ import { Promise } from "./rsvp/promise";
import
{
denodeify
}
from
"
./rsvp/node
"
;
import
{
all
,
any
}
from
"
./rsvp/all
"
;
import
{
Queue
,
ResolvedQueueError
}
from
"
./rsvp/queue
"
;
import
{
Monitor
,
ResolvedMonitorError
}
from
"
./rsvp/watcher
"
;
import
{
delay
,
timeout
}
from
"
./rsvp/timeout
"
;
import
{
hash
}
from
"
./rsvp/hash
"
;
import
{
rethrow
}
from
"
./rsvp/rethrow
"
;
...
...
@@ -16,4 +17,4 @@ function configure(name, value) {
config
[
name
]
=
value
;
}
export
{
CancellationError
,
Promise
,
EventTarget
,
all
,
any
,
Queue
,
ResolvedQueueError
,
delay
,
timeout
,
hash
,
rethrow
,
defer
,
denodeify
,
configure
,
resolve
,
reject
};
export
{
CancellationError
,
Promise
,
EventTarget
,
all
,
any
,
Queue
,
ResolvedQueueError
,
Monitor
,
ResolvedMonitorError
,
delay
,
timeout
,
hash
,
rethrow
,
defer
,
denodeify
,
configure
,
resolve
,
reject
};
lib/rsvp/watcher.js
0 → 100644
View file @
58066429
import
{
Promise
}
from
"
./promise
"
;
import
{
Queue
}
from
"
./queue
"
;
import
{
CancellationError
}
from
"
./cancellation_error
"
;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function
ResolvedMonitorError
(
message
)
{
this
.
name
=
"
resolved
"
;
if
((
message
!==
undefined
)
&&
(
typeof
message
!==
"
string
"
))
{
throw
new
TypeError
(
'
You must pass a string.
'
);
}
this
.
message
=
message
||
"
Default Message
"
;
}
ResolvedMonitorError
.
prototype
=
new
Error
();
ResolvedMonitorError
.
prototype
.
constructor
=
ResolvedMonitorError
;
function
isFunction
(
x
){
return
typeof
x
===
"
function
"
;
}
var
Monitor
=
function
()
{
var
monitor
=
this
,
promise_list
=
[],
promise
,
reject
,
notify
,
resolved
;
if
(
!
(
this
instanceof
Monitor
))
{
return
new
Monitor
();
}
function
canceller
()
{
var
len
=
promise_list
.
length
,
i
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
promise_list
[
i
].
cancel
();
}
// Clean it to speed up other canceller run
promise_list
=
[];
}
promise
=
new
Promise
(
function
(
done
,
fail
,
progress
)
{
reject
=
function
(
rejectedReason
)
{
if
(
resolved
)
{
return
;}
monitor
.
isRejected
=
true
;
monitor
.
rejectedReason
=
rejectedReason
;
resolved
=
true
;
canceller
();
return
fail
(
rejectedReason
);
};
notify
=
progress
;
},
canceller
);
monitor
.
cancel
=
function
()
{
if
(
resolved
)
{
return
;}
resolved
=
true
;
promise
.
cancel
();
promise
.
fail
(
function
(
rejectedReason
)
{
monitor
.
isRejected
=
true
;
monitor
.
rejectedReason
=
rejectedReason
;
});
};
monitor
.
then
=
function
()
{
return
promise
.
then
.
apply
(
promise
,
arguments
);
};
monitor
.
monitor
=
function
(
promise_to_monitor
)
{
if
(
resolved
)
{
throw
new
ResolvedMonitorError
();
}
var
queue
=
new
Queue
()
.
push
(
function
()
{
return
promise_to_monitor
;
})
.
push
(
function
(
fulfillmentValue
)
{
// Promise to monitor is fullfilled, remove it from the list
var
len
=
promise_list
.
length
,
promise_to_monitor
,
new_promise_list
=
[],
i
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
promise_to_monitor
=
promise_list
[
i
];
if
(
!
(
promise_to_monitor
.
isFulfilled
||
promise_to_monitor
.
isRejected
))
{
new_promise_list
.
push
(
promise_to_monitor
);
}
}
promise_list
=
new_promise_list
;
},
function
(
rejectedReason
)
{
if
(
rejectedReason
instanceof
CancellationError
)
{
if
(
!
(
promise_to_monitor
.
isFulfilled
&&
promise_to_monitor
.
isRejected
))
{
// The queue could be cancelled before the first push is run
promise_to_monitor
.
cancel
();
}
}
reject
(
rejectedReason
);
throw
rejectedReason
;
},
function
(
notificationValue
)
{
notify
(
notificationValue
);
return
notificationValue
;
});
promise_list
.
push
(
queue
);
return
this
;
};
};
Monitor
.
prototype
=
Object
.
create
(
Promise
.
prototype
);
Monitor
.
prototype
.
constructor
=
Monitor
;
export
{
Monitor
,
ResolvedMonitorError
};
test/tests/extension_test.js
View file @
58066429
...
...
@@ -2294,7 +2294,7 @@ describe("`RSVP.Queue`", function () {
it
(
'
should be fulfilled when the queue is empty
'
,
function
(
done
)
{
var
queue
=
new
RSVP
.
Queue
();
queue
.
push
(
function
()
{
return
RSVP
.
delay
(
3
0
);
return
RSVP
.
delay
(
2
0
);
});
setTimeout
(
function
()
{
...
...
@@ -2341,7 +2341,7 @@ describe("`RSVP.Queue`", function () {
it
(
'
should be rejected if one entry is rejected
'
,
function
(
done
)
{
var
queue
=
new
RSVP
.
Queue
();
queue
.
push
(
function
()
{
return
RSVP
.
timeout
(
3
0
);
return
RSVP
.
timeout
(
2
0
);
});
setTimeout
(
function
()
{
...
...
@@ -2439,3 +2439,230 @@ describe("`RSVP.Queue`", function () {
});
});
});
describe
(
"
`RSVP.Monitor`
"
,
function
()
{
describe
(
"
`ResolvedMonitorError`
"
,
function
()
{
describe
(
"
`ResolvedMonitorError` constructor
"
,
function
()
{
it
(
'
should exist and have length 1
'
,
function
()
{
assert
(
RSVP
.
ResolvedMonitorError
);
assert
.
equal
(
RSVP
.
ResolvedMonitorError
.
length
,
1
);
});
it
(
'
should be a constructor
'
,
function
()
{
var
error
=
new
RSVP
.
ResolvedMonitorError
();
assert
.
equal
(
Object
.
getPrototypeOf
(
error
),
RSVP
.
ResolvedMonitorError
.
prototype
,
'
[[Prototype]] equals ResolvedMonitorError.prototype
'
);
assert
.
equal
(
error
.
constructor
,
RSVP
.
ResolvedMonitorError
,
'
constructor property of instances is set correctly
'
);
assert
.
equal
(
RSVP
.
ResolvedMonitorError
.
prototype
.
constructor
,
RSVP
.
ResolvedMonitorError
,
'
constructor property of prototype is set correctly
'
);
});
it
(
'
should throw a `TypeError` if not given a string
'
,
function
()
{
assert
.
throws
(
function
()
{
var
error
=
new
RSVP
.
ResolvedMonitorError
({});
// ... jslint forces to use the variable
error
.
foo
=
"
bar
"
;
},
TypeError
);
});
it
(
'
should be throwable
'
,
function
()
{
assert
.
throws
(
function
()
{
throw
new
RSVP
.
ResolvedMonitorError
();
},
RSVP
.
ResolvedMonitorError
);
});
});
describe
(
"
`ResolvedMonitorError` instance
"
,
function
()
{
it
(
'
must be an instance of Error
'
,
function
()
{
var
error
=
new
RSVP
.
ResolvedMonitorError
();
assert
(
error
instanceof
Error
);
});
it
(
'
must have a `name` property with value `resolved`
'
,
function
()
{
var
error
=
new
RSVP
.
ResolvedMonitorError
();
assert
.
equal
(
error
.
name
,
"
resolved
"
);
});
it
(
'
must have a `message` property with the message value
'
,
function
()
{
var
error
=
new
RSVP
.
ResolvedMonitorError
(
"
Foo
"
);
assert
.
equal
(
error
.
message
,
"
Foo
"
);
});
it
(
'
must have a default `message` property to `Default Message`
'
,
function
()
{
var
error
=
new
RSVP
.
ResolvedMonitorError
();
assert
.
equal
(
error
.
message
,
"
Default Message
"
);
});
});
});
describe
(
"
`Monitor` constructor
"
,
function
()
{
it
(
'
should exist and have length 0
'
,
function
()
{
assert
(
RSVP
.
Monitor
);
assert
.
equal
(
RSVP
.
Monitor
.
length
,
0
);
});
it
(
'
should be a constructor
'
,
function
()
{
var
monitor
=
new
RSVP
.
Monitor
();
assert
.
equal
(
Object
.
getPrototypeOf
(
monitor
),
RSVP
.
Monitor
.
prototype
,
'
[[Prototype]] equals Monitor.prototype
'
);
assert
.
equal
(
monitor
.
constructor
,
RSVP
.
Monitor
,
'
constructor property of instances is set correctly
'
);
assert
.
equal
(
RSVP
.
Monitor
.
prototype
.
constructor
,
RSVP
.
Monitor
,
'
constructor property of prototype is set correctly
'
);
});
it
(
'
should return a new promise
'
,
function
()
{
var
promise
=
new
RSVP
.
Monitor
();
assert
(
promise
instanceof
RSVP
.
Monitor
);
assert
(
promise
instanceof
RSVP
.
Promise
);
});
it
(
'
should work without `new`
'
,
function
()
{
var
promise
=
RSVP
.
Monitor
();
assert
(
promise
instanceof
RSVP
.
Monitor
);
assert
(
promise
instanceof
RSVP
.
Promise
);
});
});
describe
(
"
`monitor`
"
,
function
()
{
it
(
'
should be a function
'
,
function
()
{
var
monitor
=
new
RSVP
.
Monitor
();
assert
.
equal
(
typeof
monitor
.
monitor
,
"
function
"
);
});
it
(
'
should return the same monitor instance
'
,
function
()
{
var
monitor
=
new
RSVP
.
Monitor
(),
result
=
monitor
.
monitor
();
assert
.
equal
(
result
,
monitor
);
});
it
(
'
should throw if the monitor is rejected
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
();
monitor
.
cancel
();
setTimeout
(
function
()
{
assert
.
throws
(
function
()
{
monitor
.
monitor
();
},
RSVP
.
ResolvedMonitorError
);
done
();
},
20
);
});
});
describe
(
"
`Monitor` instance
"
,
function
()
{
it
(
'
should not be rejected without any call
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
();
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isRejected
,
undefined
);
done
();
},
20
);
});
it
(
'
a fulfillment does not impact the monitoring
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
();
monitor
.
monitor
(
"
ok
"
);
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isFulfilled
,
undefined
);
assert
.
equal
(
monitor
.
isRejected
,
undefined
);
done
();
},
20
);
});
it
(
'
should be rejected if one entry is rejected
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
();
monitor
.
monitor
(
RSVP
.
timeout
(
30
));
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isRejected
,
undefined
);
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isRejected
,
true
);
done
();
},
20
);
},
20
);
});
it
(
'
get the rejectedReason from the rejected entry
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
();
monitor
.
monitor
(
RSVP
.
timeout
(
1
));
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isRejected
,
true
);
assert
.
equal
(
monitor
.
rejectedReason
,
"
Timed out after 1 ms
"
);
done
();
},
20
);
});
it
(
'
reject cancels the remaining promise
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
(),
pushed_result
=
RSVP
.
delay
(
1000
);
monitor
.
monitor
(
RSVP
.
timeout
(
1
));
monitor
.
monitor
(
pushed_result
);
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isRejected
,
true
);
assert
.
equal
(
monitor
.
rejectedReason
,
"
Timed out after 1 ms
"
);
assert
.
equal
(
pushed_result
.
isRejected
,
true
);
assert
.
equal
(
pushed_result
.
rejectedReason
,
"
cancel: Default Message
"
);
done
();
},
20
);
});
it
(
'
cancel also cancels the remaining promise
'
,
function
(
done
)
{
var
monitor
=
new
RSVP
.
Monitor
(),
pushed_result
=
RSVP
.
delay
(
1000
);
monitor
.
monitor
(
pushed_result
);
monitor
.
cancel
();
setTimeout
(
function
()
{
assert
.
equal
(
monitor
.
isRejected
,
true
);
assert
(
monitor
.
rejectedReason
instanceof
RSVP
.
CancellationError
);
assert
.
equal
(
pushed_result
.
isRejected
,
true
);
assert
.
equal
(
pushed_result
.
rejectedReason
,
"
cancel: Default Message
"
);
done
();
},
20
);
});
// it("notify should be propagated until `then`", function (done) {
// var monitor = new RSVP.Monitor(), responses = [];
//
// monitor.then(null, null, function (notification) {
// responses.push(notification);
// });
//
// monitor.monitor(
// new RSVP.Promise(function (resolve, reject, progress) {
// progress("hello");
// })
// );
//
// setTimeout(function () {
// assert.equal(responses[0], "hello");
// done();
// }, 20);
// });
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment