Git Product home page Git Product logo

Comments (20)

seldomU avatar seldomU commented on May 5, 2024 2

We are using JavaScript async/await and I think we only made one change near Blockly's core for it: add the async keyword to the procedure_def(no)return generator and the await keyword to procedure_call(no)return. The remaining changes are in our own blocks:
(1) All blocks that generate a function definition have to add the async keyword. That's typically the program's main function and a bunch of event handlers.
(2) Blocks that represent promises need to add the await keyword.

This way we can create async programs that mix promise blocks with Blockly's standard synchronous blocks. You can see an example application here. All blocks are synchronous except for the input reading and wait blocks. There is a tab on the right side that lets you inspect the generated code.

We're also generating async Lua with the help of coroutines. You can see that here.

@RoboErikG regarding your code example. I think those questions have to be answered per application, not Blockly-wide. For non programmer users, my answers would be: everything is considered async and the caller always waits for the promise to finish.

from blockly-samples.

yar2001 avatar yar2001 commented on May 5, 2024 2

I place the following code in the custom js and all functions will become async/await successfully. Just copy it.

Blockly.JavaScript['procedures_callreturn'] = function(block) {
  // Call a procedure with a return value.
  var funcName = Blockly.JavaScript.variableDB_.getName(
      block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME);
  var args = [];
  var variables = block.getVars();
  for (var i = 0; i < variables.length; i++) {
    args[i] = Blockly.JavaScript.valueToCode(block, 'ARG' + i,
        Blockly.JavaScript.ORDER_NONE) || 'null';
  }
  var code = 'await ' + funcName + '(' + args.join(', ') + ')';
  return [code, Blockly.JavaScript.ORDER_AWAIT];
};

// ...
// when ask code
let code = Blockly['JavaScript'].workspaceToCode(workspace).replace(/(?<=^|\n)function \w+\(.*\)/g, 'async $&');

from blockly-samples.

moniika avatar moniika commented on May 5, 2024 2

I place the following code in the custom js and all functions will become async /await successfully. Just copy it.

Blockly.JavaScript.procedures_callreturn = function(a) {
    for (var b = Blockly.JavaScript.variableDB_.getName(a.getFieldValue("NAME"), Blockly.JavaScript.PROCEDURE_CATEGORY_NAME), c = [], d = a.getVars(), e = 0; e < d.length; e++)
        c[e] = Blockly.JavaScript.valueToCode(a, "ARG" + e, Blockly.JavaScript.ORDER_COMMA) || "null";
    return ["await " + b + "(" + c.join(", ") + ")", Blockly.JavaScript.ORDER_FUNCTION_CALL]
};

// ...
// when ask code
let code = Blockly['JavaScript'].workspaceToCode(workspace).replace(/(?<=^|\n)function \w+\(.*\)/g, 'async $&');

Just at a glance, I noticed in this code you will also need to update the ORDER used in 2 places (the change from ORDER_COMMA to ORDER_NONE is a recent fix in develop).

Blockly.JavaScript.procedures_callreturn = function(a) {
    for (var b = Blockly.JavaScript.variableDB_.getName(a.getFieldValue("NAME"), Blockly.JavaScript.PROCEDURE_CATEGORY_NAME), c = [], d = a.getVars(), e = 0; e < d.length; e++)
        c[e] = Blockly.JavaScript.valueToCode(a, "ARG" + e, Blockly.JavaScript.ORDER_NONE) || "null";
    return ["await " + b + "(" + c.join(", ") + ")", Blockly.JavaScript.ORDER_AWAIT]
};

from blockly-samples.

RoboErikG avatar RoboErikG commented on May 5, 2024

This is already possible using Neil's JS-Interpreter. There shouldn't need to be any specific support for it in Blockly since you can generate async code just as easily as synchronous code.

I don't think having a global switch in the generator to mark everything async makes sense, since many functions don't have a return and have no reason to run async. Let me know if I'm missing something.

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

Surely, with the interpreter it would work, but the sandbox of the interpreter consumes performance and memory.

Iā€˜d like to add a Property to async commands, so the outside function can look if any inside block needs an await, and so I will create the async outside around. (hopefully this is possible)

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

@RoboErikG can we reopen?

from blockly-samples.

RoboErikG avatar RoboErikG commented on May 5, 2024

Hmm...I can see the use for it but I'm not sure we'd want to support it in core Blockly. Are you able to share a link to a project where you're using this feature so we could look at it and discuss internally?

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

I've not yet implemented it, I wanted to know if it will be supported. Problem is, I would not like to copy most of the javascript generation code, only to add this feature, and need to maintain it as a different fork.

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

Not will, if it has the chance to be supported.

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

for example, see here my block i did for ioBroker:

2019-01-25 22 28 32

see the wait block (warten), if it is done without async/await the blockly would get really complex

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

also much more code is returning nowdays, so I think it would create a much greater use base

from blockly-samples.

RoboErikG avatar RoboErikG commented on May 5, 2024

If there's a minimal change to generators that could be made to make this an option we'd consider supporting it.

There's a lot of corner cases that would need to be considered, though, and it's not clear what an end user's expectation would be if, for example, you did the following:

set 'foo' to 5;
call myFunc()
if foo = 5
print "this";
else
print "that";

define myFunc
wait 1 second
set foo to 10

Should myFunc be async? Would users have any idea when something is async vs not async? Do you need UI to show it? How do you distinguish that from cases where the user wants to pause execution for a bit?

from blockly-samples.

AnmAtAnm avatar AnmAtAnm commented on May 5, 2024

Currently, all of the blocks we ship with Blockly work in all five languages. Continuations are not available in ES5, PHP, Python, Lua, or Dart 1 (that I can find), and Continuation Passing Style (the functional programming equivalent) would produce code that is strange to a lot of users.

We probably need to have a discussion before committing to support a feature for only one or two languages.

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

I think blockly is mostly used for javascript (where continuations exist is ES6, and current browsers all support them).
and it should be optional, i will look, maybe changes are only needed in codegen, i want optional async support so for example not experienced users could create a sleep in a loop without defining a sub function.
if someone would not define async block, nothing should be changed.

Python: https://docs.python.org/3/library/asyncio-task.html
Dart: https://www.dartlang.org/articles/language/await-async#await-expressions

from blockly-samples.

AnmAtAnm avatar AnmAtAnm commented on May 5, 2024

Blockly is used by a large number of apps that don't generate JavaScript. Scratch, MakeCode, BlockDuino are all significant examples.

Blockly intentionally supports older browsers because schools, libraries, and developing nations often do not have the resources to maintain systems with the latest updates (if they have technical staff, at all).

And you're right... Python should have been included in the languages that support it. 3/5 is getting close to a solid case to support it.

I would want to see it optional, off by default, and easy to test in tests/playground.html. For each of JavaScript, Python, and Dart.

It is probably easiest to start by writing a demo that just overrides the JavaScript generator for functions and function calls, and proves the utility of the feature.

from blockly-samples.

jogibear9988 avatar jogibear9988 commented on May 5, 2024

yes, but as I said, I'd like that the support is optional. So noone has to use it, but if it's needed it's there...

from blockly-samples.

claytongulick avatar claytongulick commented on May 5, 2024

I'd like to jump into this also with a thumbs up, +1, etc...

For my use case, I want to use blockly as a low-code environment for semi-technical staff to generate flows in a designer environment.

The generated script will be run in Node.

Part of the core API that will be exposed to the blockly environment will be the ability to load/save values (from a mongo document - all async), call certain external API's (all async), and to issue notifications that need to await a human response. Having a clean way to execute async blocks is pretty critical to this use case.

I love the project! For now, since this is such a core requirement, I'll have to do a fork to support async blocks, but would love to issue a PR and/or collaborate on how this could be added to core.

Thanks!!

from blockly-samples.

RestlessRabbits avatar RestlessRabbits commented on May 5, 2024

@seldomU : Would you mind going a bit further into detail about your changes and files?

I try to chain blocks that handle requests and deliver a promise/value (when resolved) and I would like to avoid using Neil's JS-Interpreter if possible.

That's why I tried to apply the changes you described, but I still run into the error Invalid code generated: [object Promise] and I'm a bit puzzled at the moment.

Thank you very much in advance!

from blockly-samples.

seldomU avatar seldomU commented on May 5, 2024

That sounds like your block's code generator returns an actual promise instead of a code snippet. Just to clarify, the code generation itself stays synchronous - async/await have to be added to the generated code. Here's an example code generator for awaiting a promise:

Blockly.JavaScript['wait_a_minute'] = function(block){
    return "await new Promise( resolve => setTimeout(resolve, 60000))\n;";
}

I hope that answers your question.

from blockly-samples.

maribethb avatar maribethb commented on May 5, 2024

Moving this to samples as a feature request for a JavaScript generator that supports async/await

from blockly-samples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.