Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Non-blocking QML

Non-blocking QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
javascriptjavascript qmlc++asynchronouspromise
4 Posts 2 Posters 5.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • romsharkovR Offline
    romsharkovR Offline
    romsharkov
    wrote on last edited by romsharkov
    #1

    Situation
    You either have a QObject derivative that exposes a Q_INVOKABLE method to QML, say myapi.myfunc.. or you have a pure JavaScript function myjsfunc defined in the QML code. In both you do some heavy calculations and/or (network) I/O.

    Problem
    First: both myapi.myfunc and myjsfunc are asynchronous and needs proper async handling
    Second: You don't want neither myapi.myfunc nor myjsfunc to block the event loop while it's executing

    Possible Solution
    Return a Promise object! and let the user define the handling on it. In QML/JavaScript you can then define some asynchronous logic this way:

    import "myfsfunc.js" as JsBusinessLogic
    
    SomeItem {
    	onSomething: {
    		myapi.myfunc(...)
    		.then(
    			function(firstResult) {
    				//success! make another async call
    				return JsBusinessLogic.myjsfunc(firstResult)
    			},
    			function(err, msg) {
    				//failure! myfunc returned an error
    			}
    		)
    		.then(
    			function(secondResult) {
    				//success! second call succeeded, EXIT
    			},
    			function(err, msg) {
    				//failure! second call returned an error  
    			}
    		)
    		.catch(function() {
    			//something went seriously wrong
    		})
    	}
    }
    

    Meanwhile myjsfunc could look somewhat like this:

    function myjsfunc() {
    	return new Promise(function(resolve, reject) {  
    		//do some heavy lifting...
    		if(result == good) {
    			resolve(result)
    			return
    		}
    		reject("baaaad results, error!")
    	})
    }
    

    The promise object allows easy chaining of async operations and proper error and exception handling, but it still wont't change the fact that it's executed by the event loop and will inevitably block it, which ofcourse is unacceptable.

    Question
    So.... to make the async Promise non-blocking, I'd need to implement the Promise class in a way that uses a thread pool to execute the Promises in the background?
    This way when you call an invokable C++ method or a JS function both create and return a Promise object and exit! not blocking the loop any longer!, right?!
    The promise itself is then executed in a separate thread from the thread pool in the background. When it's finished its calculation and/or waiting for external resources it will run the JS handlers defined by then() or catch() in the event loop again, which won't block much.

    So did I correctly understand it? Would such kind of a Promise implementation work as described? Or is there probably an easier way?

    Thanks!


    P.S.
    You might ask me why I'm implementing parts of the business logic in pure JavaScript when JS is not meant to be used for this in Qt? Well... you see.. executing 3rd party C++ is not an option if you want to build a safe OS basis, that's why JavaScript does the logic, JavaScript is easily sandboxed by the QQmlEngine while C++ is extraordinary hard to sandbox. Also using JavaScript for logic like this is what it was eventually designed for.. it's a scripting language and I use it to glue low-level modules and APIs together, just in an asynchronous, non-blocking way.

    1 Reply Last reply
    1
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      This is the kind of things you become Qt Champion for: https://github.com/benlau/quickpromise

      P.S.
      Big up to the way you ask questions!

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      romsharkovR 1 Reply Last reply
      2
      • VRoninV VRonin

        This is the kind of things you become Qt Champion for: https://github.com/benlau/quickpromise

        P.S.
        Big up to the way you ask questions!

        romsharkovR Offline
        romsharkovR Offline
        romsharkov
        wrote on last edited by romsharkov
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • romsharkovR Offline
          romsharkovR Offline
          romsharkov
          wrote on last edited by
          #4

          After a detailed research of various asynchronous techniques such as Promises, Futures, Tasks and Reactive Extensions we came with a new paradigm that solved all our asynchronous problems very elegantly: The Streams Paradigm

          It's inspired by the reactive approach, though superior in many aspects such as abstraction, abortion, resumables etc.

          It's a completely rethought way of writing declarative code, making complex asynchronous operations and transactions (and probably even concurrency) a piece of cake! Nearly everything can be represented, thus abstracted away by a stream..

          • UI Elements
          • Sockets
          • Requests (HTTP etc.)
          • Calculations
          • the list goes on...

          This way streams become a consistent protocol of asynchronous and concurrent communication between various application components ranging from the UI frontend to the networked backend.

          We published the first beta release of a QML implementation with a working example aboard, be sure to check it out!

          https://qbeon.github.io/QuickStreams/

          1 Reply Last reply
          3

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved