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