Jiri Zaloudek
Jiri Zaloudek

Reputation: 61

Promise() as text in Label

considering:

function calculateDate(input) {
    var result = something_this_takes_too_much_of_the_time * input;
}

Repeater {
    count: 999

    Label {
        text: return (new Promise(resolve =>   calculateDate(somevalue)   )).then(text => text)
    }
}

as far as await function does not work in QML, Promise is good alternative not to block GUI when calculateDate() is calculating and text should be slowly populating one by one

this is at least my udnerstanding of Promise(), never used it before unfortunatelly, this does not work, it gives me error:

Unable to assign QJSValue to QString

when I try:

return (new Promise(resolve =>   calculateDate()   )).then(text => text.toString())
return (new Promise(resolve =>   calculateDate().toString()   )).then(text => text)

but:

return (new Promise(resolve =>   calculateDate()   )).then(text => text).toString()

only display text as "[object Promise]" - which is expected of course

so how do I achive what I am looking for?

Upvotes: 0

Views: 76

Answers (1)

Stephen Quan
Stephen Quan

Reputation: 26096

Promise is not the magic bullet you think it is.

If calculateDate() blocks the UI thread. Putting it inside a Promise will not resolve blocking the UI thread. If you want to know how to reengineer calculateDate() so that it does not block the UI thread, you will need to go into some details to what it actually does.

As to how to get the Promise syntax correct, I can help you here with the following example:

import QtQuick
import QtQuick.Controls
Page {
    function calculateDate(input) {
        return input;
    }

    ListView {
        model: 99
        anchors.fill: parent
        delegate: Label {
            text: "..."
            Component.onCompleted: 
                Promise.resolve()
                .then( () => calculateDate(index) )
                .then( (t) => text = t )
        }
    }
}

In summary, the things I changed were:

  • Make calculateDate() return something, your implementation doesn't return anything
  • Move Promise logic to Component.onCompleted since it's a "program" it cannot be assign to the text property declaratively, it needs to run
  • To demonstrate Promise changing, I typically start the first with Promise.resolve then I can list the chain below it with a nice indent.
  • Instead of Repeater I prefer to use ListView which gives me scrolling as well

As to async/await handling in QML have a look at this question where I posted some alternates including generator/yield syntax. JS Async Function in QML

Upvotes: 0

Related Questions