Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. From JavaScript async operations to C++/Qt
Forum Updated to NodeBB v4.3 + New Features

From JavaScript async operations to C++/Qt

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 5 Posters 2.6k Views 5 Watching
  • 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.
  • Y Offline
    Y Offline
    yugosonegi
    wrote on last edited by
    #1

    I've been coding in JavaScript using the new async/await operations along with Promises and I wanted to create the same thing I did using C++/Qt. That is my code in JavaScript:

    const request = require('async-request')
    
    class Biz {}
    
    class Foo extends Biz {
      async call() {
        let response = await request('https://httpbin.org/uuid')
        return JSON.parse(response['body'])
      }
    }
    
    class Bar extends Biz {
      async call() {
        let response = await request('https://httpbin.org/uuid')
        return JSON.parse(response['body'])
      }
    }
    
    class Container {
      constructor() {
        this.storage = []
      }
    
      register(obj) {
        this.storage.push(obj)
      }
    
      call() {
        Promise.all(this.storage.map(obj => obj.call()))
        .then(result => console.log([].concat(...result)));
      }
    }
    
    const container = new Container
    container.register(new Foo)
    container.register(new Bar)
    container.call()
    

    You don't have to understand everything but I'm going to show you the parts that is most important here.

    I have a container that will store instances of a type in this case is Biz.
    The container is responsible to call the call method from the registered instances asynchronously.

    Looking at the call method from the classes Foo and Bar you will notice an async keyword that means that we can use the keyword await inside of that method. In this case I used await connect(...) .

    The await operator is used to wait for a Promise. It can only be used inside an async function.
    Returns the fulfilled value of the promise, or the value itself if it's not a Promise.

    In this case I have the value of the promise that is the return of the request, I got the body as a Json and returned.

    Promise.all(this.storage.map(obj => obj.call()))
    .then(result => console.log([].concat(...result)));
    

    In JavaScript we have the Promise.all:

    The Promise.all() method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.

    So as parameter I passed a this.storage.map:

    The map() method creates a new array with the results of calling a provided function on every element in the calling array.

    Basically map will give me each value of the array so I can handle it and then return anything I want and it will create a new array based on the returns. In this case I'm returning the return of the obj.call() basically.

    The then is the callback for when the Promise is resolved so I can handle it's value.

    The return in this case will be something similar to:

    [[{ uudi: '...' }], [{ uuid: '...' }]]
    

    And as you can see it has an array of two arrays with objects inside, so I had to make this array flatten so it would look like this:

    [{ uudi: '...' }, { uuid: '...' } ]
    

    And for this I used this: [].concat(...results) from the then (the resolved single Promise that contains the value from both call.

    This is not that important in C++/Qt, the most important part here is the async part, of how to create something similar to that, that is creating a container of instances, calling each method asynchronously, where each method that has been called will have a heavy operation such as an http request or something like that and return values and then the caller method from the container will have the values from the calls.

    benlauB 1 Reply Last reply
    0
    • Y Offline
      Y Offline
      yugosonegi
      wrote on last edited by
      #2

      Anyone to help me with that?

      mrjjM JonBJ 2 Replies Last reply
      0
      • Y yugosonegi

        Anyone to help me with that?

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @yugosonegi

        I wish i could but i have zero idea about javascript. it sounds like QFuture and QtConcurrent but im not sure

        Promise.all(this.storage.map(obj => obj.call())) no idea what this means

        QConcurrent can run a list in threads.

        so you have a list of Biz and you want to call each Bizz function so they all run concurrent?

        The network manager is async
        http://doc.qt.io/qt-5/qnetworkaccessmanager.html

        1 Reply Last reply
        1
        • Y yugosonegi

          Anyone to help me with that?

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #4

          @yugosonegi

          If you want to do it something like the way you have done in JS, have you looked at https://github.com/benlau/asyncfuture

          1 Reply Last reply
          1
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            Looks like you might be interested by @benlau's AsyncFuture.
            Or QtPromise
            Or Qt-Promise

            WARNING: I haven't tested them but they look like what you are on the hunt for.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            2
            • Y yugosonegi

              I've been coding in JavaScript using the new async/await operations along with Promises and I wanted to create the same thing I did using C++/Qt. That is my code in JavaScript:

              const request = require('async-request')
              
              class Biz {}
              
              class Foo extends Biz {
                async call() {
                  let response = await request('https://httpbin.org/uuid')
                  return JSON.parse(response['body'])
                }
              }
              
              class Bar extends Biz {
                async call() {
                  let response = await request('https://httpbin.org/uuid')
                  return JSON.parse(response['body'])
                }
              }
              
              class Container {
                constructor() {
                  this.storage = []
                }
              
                register(obj) {
                  this.storage.push(obj)
                }
              
                call() {
                  Promise.all(this.storage.map(obj => obj.call()))
                  .then(result => console.log([].concat(...result)));
                }
              }
              
              const container = new Container
              container.register(new Foo)
              container.register(new Bar)
              container.call()
              

              You don't have to understand everything but I'm going to show you the parts that is most important here.

              I have a container that will store instances of a type in this case is Biz.
              The container is responsible to call the call method from the registered instances asynchronously.

              Looking at the call method from the classes Foo and Bar you will notice an async keyword that means that we can use the keyword await inside of that method. In this case I used await connect(...) .

              The await operator is used to wait for a Promise. It can only be used inside an async function.
              Returns the fulfilled value of the promise, or the value itself if it's not a Promise.

              In this case I have the value of the promise that is the return of the request, I got the body as a Json and returned.

              Promise.all(this.storage.map(obj => obj.call()))
              .then(result => console.log([].concat(...result)));
              

              In JavaScript we have the Promise.all:

              The Promise.all() method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.

              So as parameter I passed a this.storage.map:

              The map() method creates a new array with the results of calling a provided function on every element in the calling array.

              Basically map will give me each value of the array so I can handle it and then return anything I want and it will create a new array based on the returns. In this case I'm returning the return of the obj.call() basically.

              The then is the callback for when the Promise is resolved so I can handle it's value.

              The return in this case will be something similar to:

              [[{ uudi: '...' }], [{ uuid: '...' }]]
              

              And as you can see it has an array of two arrays with objects inside, so I had to make this array flatten so it would look like this:

              [{ uudi: '...' }, { uuid: '...' } ]
              

              And for this I used this: [].concat(...results) from the then (the resolved single Promise that contains the value from both call.

              This is not that important in C++/Qt, the most important part here is the async part, of how to create something similar to that, that is creating a container of instances, calling each method asynchronously, where each method that has been called will have a heavy operation such as an http request or something like that and return values and then the caller method from the container will have the values from the calls.

              benlauB Offline
              benlauB Offline
              benlau
              Qt Champions 2016
              wrote on last edited by
              #6

              @yugosonegi In C++, the technique to implement async/await is called as coroutines. But unfortunately, that Qt doesn't support yet. You need to seek for 3rd party library's support.

              In case you are satisfied with traditional promise chain in Javascript, you may consider my AsyncFuture project. It turns a QFuture object into a promise-like object, and it could be chained.

              Remarks: The way of handling reject (aka cancel in QFuture) in a promise chain is not identical to Javascript. As it is designed for a multi-threaded actor model. Calling the cancel will cancel everything in the chain.

              1 Reply Last reply
              2
              • Y Offline
                Y Offline
                yugosonegi
                wrote on last edited by
                #7

                Thank you guys a lot for that, I'll be studying in order to see what is better for me.

                1 Reply Last reply
                0

                • Login

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