简体   繁体   中英

Why can't synchronous actions in Reflux also be used as promises?

In my code, I use the async actions as promises pattern heavily. Here's an example:

var actions = Reflux.createActions({connectToFacebook: {asyncResult: true}});

actions.connectToFacebook.listenAndPromise(function(){

    var facebookOauthPromise = _doFacebookConnect(); // implementation elided

    return facebookOauthPromise.then(function(token){
        return $.post('/api/facebook/connect', {token: token});
    });
});

var promise = actions.connectToFacebook();
promise.then(function(){
    // do something on success
});

This works great. When first the oAuth and then the POST request completes, connectToFacebook.completed , and my outer promise.then are fired as expected.

However, I had to add {sync: true} to the definition of the action because the implementation of _doFacebookConnect calls window.open , which will be blocked unless called on the same call stack as a user click event. Reflux by default will use _.nextTick when dispatching the event, so it's no longer on the same stack.

When I do this, the action still works properly, and the pop-up blocker is no longer a problem. However, my outer promise.then fails to execute, because the return value of actions.connectToFacebook() is now undefined instead of the promise I returned from listenAndPromise .

Why does Reflux suddenly stop passing through the returned promise, and is there any way to elegantly work around this?

I just found a way to hack around it, by overriding action.trigger rather than using action.listenAndPromise() :

actions.connectToFacebook.trigger = function(){

    var facebookOauthPromise = _doFacebookConnect(); // implementation elided

    var promise = facebookOauthPromise.then(function(token){
        return $.post('/api/facebook/connect', {token: token});
    });

    this.promise(promise);
    return promise;
};

It does seem to cover both dispatching connectToFacebook.completed (because of the this.promise() call and returning the promise (by explicitly doing so).

However, I'm still not clear on why Reflux doesn't do this automatically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM