Reputation: 117
So I've been trying to google my answer but had no luck finding it. I'm wondering how I can await a value to be defined by the use of promises, not a brute-force method like using:
while(true){ Check for condition and then break }
This was my initial brute-force approach but It obviously isn't a good solution:
const awaitToken = new Promise((resolve, reject) => {
while(true){
if(getState().auth.token){
resolve(true)
break;
}
}
})
Upvotes: 0
Views: 890
Reputation: 508
Here is a non-blocking solution for using synced functions an easy way in promises. An additional timeout can save you a lot of waiting time.
let arrivedToken = new Promise((resolve, reject) => {
/* how often you wanna check? */
let interval = 20;
/*how long do you want to wait? */
let timeOut = 4000;
let timer = setInterval(() => {
timeOut -= interval;
if (timeOut < 1) {
clearInterval(timer);
reject(new Error('catching token timed out'));
}
let token = getState().auth.token;
if (token)
resolve(token);
}, interval);
};
so you can handle the success or even the failure:
arrivedToken
.then(token => {
/* whatever you want */
})
.catch(error => {
/* handle the timeout */
})
;
Upvotes: 1
Reputation: 2357
Push vs. Pull
I'm going to make some assumptions given the way you asked your question: The assumption is no-one has explained the Push v Pull dichotomy. It's extremely important to understand to solve these types of problems in the future without SO's community.
Promises and callbacks were designed by the ECMA body to enable developers to PULL for results of asynchronous tasks. You can think of PULL-ing as picking up the telephone and calling your friend asking him if your package has been delivered at his address that you used on your delivery form. Obviously you're not going to stay on the call until the package arrives so you continuously have to iterate this process until your friend says, "yes, you're package has arrived" (e.g. Promise.resolve(package) || cb('package has arrived')
).
Then the ECMA body delivered us ES8. And with it, a PUSH methodology which solves exactly the problem that you're beating your head against quite admirably I might add. The async/await
dichotomy enables a developer to no longer have to pick up the phone and call their friend. Instead, your friend picks up the phone and calls you and says "Hey man, come get your stuff off my porch, it's arrived." This is a PUSH. async/await
& generators
More Verbosity on async/await
theory if you desire here
Solutions
function * fetchToken() {
const { auth } = getToken(); // getToken() is asynchronous and BLOCKs control flow until value is returned.
yield auth.token;
}
const tokenGen = fetchToken();
const { value: token } = tokenGen().next();
console.log('token: ', token); // [jwt token]
async function fetchToken() {
const { auth } = await getToken(); // await BLOCK's control flow until the function resolves.
return auth.token;
}
const token = fetchToken();
console.log('token: ', token); // [jwt token]
Upvotes: 0
Reputation: 21130
Redux allows you to subscribe to a store. The callback will be called whenever an action is dispatched.
Meaning you could do something like this:
const awaitToken = new Promise(resolve => {
if (getState().auth.token) return resolve(true);
const unsubscribe = subscribe(() => {
if (!getState().auth.token) return;
unsubscribe();
resolve(true);
});
});
Additional info about subscribe
can be found here. You might also want to add a timeout, but that might depend on the use case.
Upvotes: 0