-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clientside Callback Promise Handling #2009
Clientside Callback Promise Handling #2009
Conversation
I feel like this feature was way to easy to implement. This is most likely due to a large amount of functionality and edge cases I'm unaware of. Would love your input/guidance on what else you'd need to see for this to be complete @chriddyp and @alexcjohnson. |
I'm not surprised this is pretty easy at this point - there have been a bunch of architectural changes bringing the async server-side callback execution and sync client-side execution closer to parallel. We just hadn't gotten around to trying it - and adding tests to ensure it works as intended. But I wonder if this wouldn't already work just by removing the test for a promise? I see later in the process we do a different test for promises (coming I presume from server-side callbacks) and we await these there: dash/dash/dash-renderer/src/observers/executingCallbacks.ts Lines 21 to 24 in f6abdfb
Did you try this and see it fail? My main concern with blanket converting the synchronous function to async is whether we'll cause multiple page reflows/repaints in the case of multiple concurrent clientside callbacks, which can slow things down or make them look unnecessarily jittery. This is why for example plotly.js makes its own Anyway as I alluded to above the main additional thing this will need is some tests. Perhaps:
function cb(inputVal) {
return new Promise(function(resolve) {
window.callbackDone = function(deferredVal) {
resolve(inputVal + ' - ' + deferredVal);
}
})
} then in the test code, wait for the serverside output to be visible then call: dash_duo.driver.execute_script("window.callbackDone('the wait is over!')") |
Hey @alexcjohnson! Thanks for your review, was really detailed and helped a tonne to know what direction you wanted to go as the project owner. Quickly to begin, I did try removing the test for a promise, no dice unfortunately. I've added the tests you suggested and they're passing well. If you (or anyone else) glance across them and sanity check to ensure they do what they're supposed to do. New tests added include:
Note: I have xfailed On the concern of converting a synchronous function to async and the desire to keep it as synchronous as possible, I completely agree. Perhaps we could determine whether the return value is a function or not (currently done here) outside of |
Nice! Lovely tests 🏆 The one additional piece that occurs to me, mainly for documentation purposes: I presume it also works if these are declared as async functions, rather than regular functions that return promises? Including using the inline syntax: app.clientside_callback(
"""
async function(val) { ... }
""",
Output(...), Input(...)
) I think we can delete
OIC, there's the whole reshaping into Now that I see it though delaying |
Yes it does. I have just added a couple more tests to cover this scenario. These two cover both
Definitely agree that, for now, the safest option is to read the If there's nothing else, I think it's just the docs to be updated and it'll be ready to merge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful! Thanks so much for your contribution @MrTeale 💃
This PR aims to be the implementation of Client-side Callback's being able to handle Promises. This feature has been long discussed and requested as seen in #1364 and in this Community Forum Discussion.
The current solution converts the error message for having a promise in a client-side callback into an
await
that gets the output from the promise instead. This does mean the client-side callback handler is now anasync function
.Will close #1364
Contributor Checklist
CHANGELOG.md