I have a plugin which depends on selected layers. I also have another plugin, which, after performing some actions, selects specific layers. What I want, is for the second plugin to select layers only after I performMenuCommand() of the first plugin. All batchPlays here are synchronous.
// 2nd plugin actions
batchPlay(actions);
batchPlay([SAVE SELECTED LAYERS ACTIONS]);
batchPlay([SELECT LAYER FOR 1ST PLUGIN ACTION]);
core.performMenuCommand({ [1ST PLUGIN MENU COMMAND ID] });
// If I leave the line bellow, performMenuCommand() always fails
// because it's executed only after all batchPlays bellow are done
// But if I comment this line out, menu command is run as expected,
// but then it wouldn't re-select the layers I need for the second plugin (obviously)
batchPlay([RE-SELECT PREVIOUSLY SAVED LAYERS ACTIONS]);
batchPlay([OTHER FINISHING ACTIONS WITHOUT CHANGING THE SELECTION]);
I see performMenuCommand() is async. Any way to make it synchronous too? Can’t find any docs (again)
P. S. Sorry for this [SYNTAX], it wouldn’t let me post because of tooLongWords
I’m still very confused about all this async/await stuff
If I add await, then I have to add async to my whole function and it becomes asynchronous, doesn’t it? Also can’t get it to work with then()
function doStuff() {
async function executeCommand(commandId) {
return await core.performMenuCommand({commandId});
}
executeCommand(-110).then(
batchPlay([RE-SELECT PREVIOUSLY SAVED LAYERS ACTIONS]);
);
}
But elsewhere I also have:
doStuff();
batchPlay([OTHER FINISHING ACTIONS WITHOUT CHANGING THE SELECTION]);
And executeCommand() promise is pending until everything is done. And for some reason when executeCommand() is finally done, layers are already re-selected. Looks like then() is performed before async is done
Correct Also, if you’re returning a promise, it’s not even necessary to add the await keyword - if you think about it, what do you want to wait for in the scope of this function? return is always the last executed line, so there’s nothing after it. Btw, if you add async to your function, everything you return will already be a promise, which can also tidy up the code. I can really recommend typescript + tslint, it makes things so much easier and literally shows you all those little details:
But again… If I add await doStuff(), then I have to add async all the way to the top function and that makes whole myPluginCommand asynchronous, doesn’t it? Wouldn’t it become something like this?
Yes, but is that a problem? I’m not sure if the commands object expects any specific function type but I kinda doubt it. And if it does, you could still just call your async function in a synchronous main() function or similar.
Alternatively, you could also do it with then, which doesn’t require the parent function to be async if I remember correctly:
doStuff().then(() => {
batchPlay([OTHER FINISHING ACTIONS WITHOUT CHANGING THE SELECTION]);
})
Spent a couple of hours now, but can’t make it work At some point I had it working, but for some reason I got something like
Can’t call then() on undefined
But now can’t even reproduce that
I now even tried passing the callback all the way up to core.performMenuCommand({commandId}).then(callback), but still performMenuCommand() is executed only after callback is done. WTH?
OK, here’s the full flow… I have batchPlay synchronous
entrypoints.setup({
commands: {
mainCommand: () => mainCommand()
}
});
const mainCommand = function () {
let result = batchPlay(
[lots, of, actions],
historyState
);
batchPlay([actions, with, IDs, from, result]);
runOtherPluginMenu(result[0].layerID);
};
const runOtherPluginMenu = function (id) {
const allSelectedLayerIds = getSelectedLayersIDs();
batchPlay([selectLayerWith_id]);
const cb = () => {
batchPlay([...reSelect_allSelectedLayerIds]);
};
const menuPath = ['menu', 'titles', 'path'];
/// Here core.performMenuCommand() never gets executed ...
// const menuItem = getMenuItemByPath(menuPath);
// core.performMenuCommand(menuItem.command).then(cb);
// ... But here it gets executed
// except that core.performMenuCommand() is run only after layers are re-selected
// by running a callback in .then() in executeCommand() function
runMenuCommand(menuPath, cb);
};
function runMenuCommand(path, callback = null) {
const menuItem = getMenuItemByPath(menuPath);
if (menuItem && typeof menuItem.command != 'undefined') {
executeCommand(menuItem.command, callback);
return;
}
if (typeof callback == 'function') {
callback();
}
}
function executeCommand(commandId, callback = null) {
core.performMenuCommand({commandId}).then(callback);
}