Skip to content

[fluxible] context.executeAction(action, null, callback) invokes the callback before the async action finishes #593

Open
@Kailang

Description

@Kailang

When using babel to compile ES2015 down, there is a bug that causes the actionContext.executeAction(action, null, callback) to invoke the callback before the async action finishes.
This bug causes the executeMultiple() to ignore the dependency chain and invokes the action before its dependencies are fulfilled.

Expected behavior

Consider the following 2 actions:

function loadView(context, params = {}, done) { }
function initViewPage(context, params, done) {
    actionContext.executeAction(loadView, () => {
        console.log('This should not be printed.');
    });
}

When executing initViewPage() action, the console log should not be printed since loadView() action never finishes.

Actual behavior

The console log is printed without waiting for the loadView() action to finish(, which should never happen).

Information about the Issue

In:
https://github.com/yahoo/fluxible/blob/master/packages/fluxible/utils/callAction.js#L29

                var syncResult = action(actionContext, payload, function (err, result) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(result);
                    }
                });
                if (isPromise(syncResult)) {
                    syncResult.then(resolve, reject);
                } else if (action.length < 3) {
                    resolve(syncResult);
                }

Especially, in:

                if (action.length < 3) {
                    resolve(syncResult);
                }

Here, the callback for any action is directly invoked if the parameter count for the action is less than 3.
Since we are using babel to compile the ES2015 down, we cannot rely on the <Func>.length property to determine if we have given the action a callback.
For example:

function loadViews(context, params = {}, done) { }

loadViews.length will be 1 because it is compiled into:

function loadViews(context) {
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var done = arguments[2];
}

by babel.
A quick way to avoid this bug is to not use the default parameters syntax in the action definition if you are using babel.

Steps to reproduce the behavior

Try the code in the first section in any babel compiled code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions