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.