Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27710] TiAPI: Support optional callback functions for async methods that typically fire events

GitHub Issuen/a
TypeStory
PriorityHigh
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sRelease 10.2.0
ComponentsTiAPI
LabelsengSchedule
ReporterChristopher Williams
AssigneeChristopher Williams
Created2020-01-08T15:04:34.000+0000
Updated2021-10-07T16:04:52.000+0000

Description

We have a number of basic operations that rely on event listener based usage to handle notifying when the operation is "complete". While this works, it can lead to a lot of boilerplate code for hanging simple one-time callback logic when the operation is complete. i.e. We often have a single listener on Ti.UI.Window#close() where we want to clean up after the windows is closed. Compare:
win.addEventListener('close', function listener (e) {
  win.removeEventListener('close', listener); // clean up this callback listener
  // do whatever other cleanup we want
});
win.close();

// versus

window.close(e => {
  // do whatever other cleanup we want
});
It would be good to review our APIs and the events we fire and see if they are explicitly tied to methods called by the developer - and if so, provide optional callback functions as the final arguments so that developers could use a more Node.JS style usage and streamline cases where you only expect a single listener/callback (though for backwards compatibility and for supporting multiple listeners we shoulder retain the event firing as well). Note that this would also position us well to add "shims" to convert these methods calls into Promise-based APIs at the JS level.
win.close().then(e => {
  // do whatever other cleanup we want
});
// or...
const closeEvent = await win.close();
// do whatever other cleanup we want

Comments

  1. Christopher Williams 2020-01-08

    Potential targets: - Ti.UI.Window#close() - Ti.UI.Window#open() - Ti.UI.View#hide() - Ti.UI.View#show() - Ti.UI.View subclasses with blur() and focus() methods (i.e. TextField, SearchBar, TextArea) - Ti.UI.RefreshControl#beginRefreshing() - Ti.UI.RefreshControl#endRefreshing() - Titanium.UI.ImageView#pause() - Titanium.UI.ImageView#resume() - Titanium.UI.ImageView#start() - Titanium.UI.ImageView#stop() Note that Ti.UI.View#animate() already supports an optional callback for this exact same use-case/style. Also note that in all these cases, these methods are already operating asynchronously so behavior isn't changing/breaking (form sync to async). They simply were typically firing off events when the operation finished.
  2. Christopher Williams 2020-01-08

    Faintly related to TIMOB-25536 - Basically I think Gary's ti.es6 project could potentially be another means of doing the callback -> Promise API wrapping, since I think he's sort of baked that in to the shim generation? cc [~gmathews]
  3. Christopher Williams 2020-02-12

    Another potential method: Ti.App.iOS.registerUserNotificationSettings - users have to register an event listener 'usernotificationsettings' to handle the success/failure of this method call async. This feels ripe for a callback/Promise.
  4. Gary Mathews 2021-05-12

    Linking to a list of potential methods of interest https://github.com/appcelerator/titanium_mobile/pull/10554#issuecomment-737611822

JSON Source