javascript - Promise() as text in Label - Stack Overflow

admin2025-04-28  2

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?

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?

Share Improve this question asked Jan 8 at 14:08 Jiri ZaloudekJiri Zaloudek 971 silver badge11 bronze badges 3
  • 2 "Promise is good alternative not to block GUI when calculateDate() is calculating and text should be slowly populating one by one": this is a misunderstanding. A JavaScript engine does not run JS code concurrently, like pre-emptive multitasking: while a function executes, no other JS code can execute. If you want multithreading, look at Web Workers. – trincot Commented Jan 8 at 14:29
  • I recommend moving heavy functions into C++ functions. That way they can be moved to different threads allowing the UI to still update. The C++ code can emit signals showing progress and/or completion. – JarMan Commented Jan 8 at 17:32
  • You need to clarify something_this_takes_too_much_of_the_time since if this blocks the one and only QML engine thread, then we need to explore why. If it doesn't (e.g. its a waiting a response from a restful service, then, we can talk about a bunch of things ranging from Promises, signal-slots, yield/generator, ...) – Stephen Quan Commented Jan 8 at 22:40
Add a comment  | 

1 Answer 1

Reset to default 0

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

转载请注明原文地址:http://anycun.com/QandA/1745851149a91233.html