quickjs_runtime/features/
setimmediate.rs

1use crate::facades::QuickJsRuntimeFacade;
2use crate::jsutils::JsError;
3use crate::quickjs_utils;
4use crate::quickjs_utils::{functions, get_global_q, objects, parse_args};
5use crate::quickjsruntimeadapter::QuickJsRuntimeAdapter;
6use libquickjs_sys as q;
7
8/// provides the setImmediate methods for the runtime
9/// # Example
10/// ```rust
11/// use quickjs_runtime::builder::QuickJsRuntimeBuilder;
12/// use quickjs_runtime::jsutils::Script;
13/// use std::time::Duration;
14/// let rt = QuickJsRuntimeBuilder::new().build();
15/// rt.eval_sync(None, Script::new("test_immediate.es", "setImmediate(() => {console.log('immediate logging')});")).expect("script failed");
16/// std::thread::sleep(Duration::from_secs(1));
17/// ```
18pub fn init(q_js_rt: &QuickJsRuntimeAdapter) -> Result<(), JsError> {
19    log::trace!("setimmediate::init");
20
21    q_js_rt.add_context_init_hook(|_q_js_rt, q_ctx| {
22        let set_immediate_func =
23            functions::new_native_function_q(q_ctx, "setImmediate", Some(set_immediate), 1, false)?;
24
25        let global = get_global_q(q_ctx);
26
27        objects::set_property2_q(q_ctx, &global, "setImmediate", &set_immediate_func, 0)?;
28        Ok(())
29    })?;
30    Ok(())
31}
32
33unsafe extern "C" fn set_immediate(
34    context: *mut q::JSContext,
35    _this_val: q::JSValue,
36    argc: ::std::os::raw::c_int,
37    argv: *mut q::JSValue,
38) -> q::JSValue {
39    log::trace!("> set_immediate");
40
41    let args = parse_args(context, argc, argv);
42
43    QuickJsRuntimeAdapter::do_with(move |q_js_rt| {
44        let q_ctx = q_js_rt.get_quickjs_context(context);
45        if args.is_empty() {
46            return q_ctx.report_ex("setImmediate requires at least one argument");
47        }
48        if !functions::is_function(context, &args[0]) {
49            return q_ctx.report_ex("setImmediate requires a functions as first arg");
50        }
51
52        QuickJsRuntimeFacade::add_local_task_to_event_loop(move |_q_js_rt| {
53            let func = &args[0];
54
55            match functions::call_function(context, func, &args[1..], None) {
56                Ok(_) => {}
57                Err(e) => {
58                    log::error!("setImmediate failed: {}", e);
59                }
60            };
61        });
62
63        quickjs_utils::new_null()
64    })
65}