1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 23:34:47 -05:00

refactor(core): Extract JsRuntime::poll_value out of JsRuntime::resolve_value (#13461)

This commit is contained in:
Rafael Ávila de Espíndola 2022-01-24 11:59:41 -05:00 committed by GitHub
parent 23d2b34d4b
commit ae0414fa35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -686,19 +686,15 @@ impl JsRuntime {
scope.perform_microtask_checkpoint(); scope.perform_microtask_checkpoint();
} }
/// Waits for the given value to resolve while polling the event loop. pub fn poll_value(
///
/// This future resolves when either the value is resolved or the event loop runs to
/// completion.
pub async fn resolve_value(
&mut self, &mut self,
global: v8::Global<v8::Value>, global: &v8::Global<v8::Value>,
) -> Result<v8::Global<v8::Value>, Error> { cx: &mut Context,
poll_fn(|cx| { ) -> Poll<Result<v8::Global<v8::Value>, Error>> {
let state = self.poll_event_loop(cx, false); let state = self.poll_event_loop(cx, false);
let mut scope = self.handle_scope(); let mut scope = self.handle_scope();
let local = v8::Local::<v8::Value>::new(&mut scope, &global); let local = v8::Local::<v8::Value>::new(&mut scope, global);
if let Ok(promise) = v8::Local::<v8::Promise>::try_from(local) { if let Ok(promise) = v8::Local::<v8::Promise>::try_from(local) {
match promise.state() { match promise.state() {
@ -706,7 +702,7 @@ impl JsRuntime {
Poll::Ready(Ok(_)) => { Poll::Ready(Ok(_)) => {
let msg = "Promise resolution is still pending but the event loop has already resolved."; let msg = "Promise resolution is still pending but the event loop has already resolved.";
Poll::Ready(Err(generic_error(msg))) Poll::Ready(Err(generic_error(msg)))
}, }
Poll::Ready(Err(e)) => Poll::Ready(Err(e)), Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending, Poll::Pending => Poll::Pending,
}, },
@ -724,8 +720,17 @@ impl JsRuntime {
let value_handle = v8::Global::new(&mut scope, local); let value_handle = v8::Global::new(&mut scope, local);
Poll::Ready(Ok(value_handle)) Poll::Ready(Ok(value_handle))
} }
}) }
.await
/// Waits for the given value to resolve while polling the event loop.
///
/// This future resolves when either the value is resolved or the event loop runs to
/// completion.
pub async fn resolve_value(
&mut self,
global: v8::Global<v8::Value>,
) -> Result<v8::Global<v8::Value>, Error> {
poll_fn(|cx| self.poll_value(&global, cx)).await
} }
/// Runs event loop to completion /// Runs event loop to completion
@ -1859,6 +1864,51 @@ pub mod tests {
} }
} }
#[tokio::test]
async fn test_poll_value() {
run_in_task(|cx| {
let mut runtime = JsRuntime::new(Default::default());
let value_global = runtime
.execute_script("a.js", "Promise.resolve(1 + 2)")
.unwrap();
let v = runtime.poll_value(&value_global, cx);
{
let scope = &mut runtime.handle_scope();
assert!(
matches!(v, Poll::Ready(Ok(v)) if v.open(scope).integer_value(scope).unwrap() == 3)
);
}
let value_global = runtime
.execute_script(
"a.js",
"Promise.resolve(new Promise(resolve => resolve(2 + 2)))",
)
.unwrap();
let v = runtime.poll_value(&value_global, cx);
{
let scope = &mut runtime.handle_scope();
assert!(
matches!(v, Poll::Ready(Ok(v)) if v.open(scope).integer_value(scope).unwrap() == 4)
);
}
let value_global = runtime
.execute_script("a.js", "Promise.reject(new Error('fail'))")
.unwrap();
let v = runtime.poll_value(&value_global, cx);
assert!(
matches!(v, Poll::Ready(Err(e)) if e.downcast_ref::<JsError>().unwrap().message == "Uncaught Error: fail")
);
let value_global = runtime
.execute_script("a.js", "new Promise(resolve => {})")
.unwrap();
let v = runtime.poll_value(&value_global, cx);
matches!(v, Poll::Ready(Err(e)) if e.to_string() == "Promise resolution is still pending but the event loop has already resolved.");
});
}
#[tokio::test] #[tokio::test]
async fn test_resolve_value() { async fn test_resolve_value() {
let mut runtime = JsRuntime::new(Default::default()); let mut runtime = JsRuntime::new(Default::default());