Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle top-level async? #360

Open
stevefan1999-personal opened this issue Sep 15, 2024 · 0 comments
Open

How to handle top-level async? #360

stevefan1999-personal opened this issue Sep 15, 2024 · 0 comments

Comments

@stevefan1999-personal
Copy link

stevefan1999-personal commented Sep 15, 2024

Far as I can tell, this is the behavior for the TLA:

@item evalScript(str, options = undefined)
Evaluate the string @code{str} as a script (global
eval). @code{options} is an optional object containing the following
optional properties:

  @table @code
  @item backtrace_barrier
  Boolean (default = false). If true, error backtraces do not list the
  stack frames below the evalScript.
  @item async
  Boolean (default = false). If true, @code{await} is accepted in the
  script and a promise is returned. The promise is resolved with an
  object whose @code{value} property holds the value returned by the
  script.
  @end table

That means even if I do this:

pub async fn eval<U: for<'js> FromJs<'js> + Send + Sync + 'static>(
        &self,
        src: &str,
    ) -> eyre::Result<U> {
        cfg_if::cfg_if! {
            if #[cfg(feature = "transpile")] {
                let syntax = infer_transpile_syntax_by_extension(get_best_transpiling())?;
                let (src, _) = self.transpile(
                    src,
                    syntax,
                    IsModule::Bool(false),
                )?;
            }
        }

        // evil hack
        let src = src.trim_end_matches(";\n");

        Ok(async_with!(self.context => |ctx| {
            let promise: Promise = ctx.eval_with_options(
                src,
                {
                    let mut options = EvalOptions::default();
                    options.global = true;
                    options.promise = true;
                    options.backtrace_barrier = true;
                    options
                }
            )?;
            promise.into_future().await
        })
        .await?)
    }

For example, if I run eval("123") It actually gives me {"value": 123}. Is there a better way than directly assuming it as a object and accessing the value props?

Here's my workaround for now:

        Ok(async_with!(self.context => |ctx| {
            let promise: Promise = ctx.eval_with_options(
                src,
                {
                    let mut options = EvalOptions::default();
                    options.global = true;
                    options.promise = true;
                    options.backtrace_barrier = true;
                    options
                }
            )?;
            let finished: Object = promise.into_future().await?;
            finished.get("value")
        })
        .await?)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant