RemoteCommand provides a simple way to execute backing bean methods with javascript.
Sometimes you need to add a dynamic callback for when the remote command completes. Each remote command, when called, returns a promise-like object you can use for that purposes. Try opening a dev console and run the function "runRemoteCommand". See below for the code.
<div class="card">
    <h:form>
        <p:remoteCommand name="rc" update="msgs" action="#{remoteCommandView.execute}"/>
        <p:remoteCommand name="rc2" update="msgs" action="#{remoteCommandView.execute}"
                         oncomplete="PF('msgsWidget').renderMessage({severity: 'info', summary: 'Data Received', detail: args.serverTime})"/>
        <h5>Basic</h5>
        <p>Execute a simple remote command by calling a javascript function.</p>
        <p:commandButton type="button" value="Send" icon="pi pi-refresh" onclick="rc()"/>
        <h5>Parameters</h5>
        <p>Passing parameters to the remote method as a javascript object or array of objects.</p>
        <p:commandButton type="button" value="Send Array" icon="pi pi-refresh" styleClass="mr-2"
                onclick="rc([{name: 'param1', value: 'foo'}, {name: 'param2', value: 'bar'}])"/>
        <p:commandButton type="button" value="Send Object" icon="pi pi-refresh"
                onclick="rc({param1: 'foo', param2: 'bar'})"/>
        <h5>Receive Values Back</h5>
        <p>Receiving values form the server as a serialized json object.</p>
        <p:commandButton type="button" value="Send" icon="pi pi-refresh" onclick="rc2()"/>
        <script>
            function runRemoteCommand(param1, param2) {
                var promise = rc([{name: 'param1', value: param1}, {name: 'param2', value: param2}]);
                promise.then(function (responseData) {
                    var serverTime = responseData.jqXHR.pfArgs.serverTime;
                    console.log("Request successful, returned server time is", serverTime);
                }).catch(function (error) {
                    console.error("Request failed", error);
                });
            }
        </script>
        <p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" widgetVar="msgsWidget" />
    </h:form>
</div>
package org.primefaces.showcase.view.ajax;
import org.primefaces.PrimeFaces;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Named;
@Named
@RequestScoped
public class RemoteCommandView {
    public void execute() {
        String param1 = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param1");
        String param2 = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param2");
        if (param1 != null || param2 != null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Executed", "param1: " + param1 + ", param2: " + param2));
        }
        else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Executed", "Using RemoteCommand."));
        }
        PrimeFaces.current().ajax().addCallbackParam("serverTime", System.currentTimeMillis());
    }
}