Agree, I think you can use the variable to store the promise directly. Another little improvement could be awaiting the promise instead of using .then, just for consistency, I'm not a big fan of mixing async/await with then (but It is just a personal preference).
This is a good point, this whole thing could be simplified to something like this gist.github.com/lmiller1990/26eb3c2d76eb8c122a0012c1e47dc15e p-defer package can be useful if you need to resolve/reject after the call for whatever reason, but in this situation it's not really necessary. After thinking this through, I don't think p-defer really makes sense in this explanation. I will add a comment to this meaning. I will leave the video as-is, happy to own this oversight and take it as a learning experience. Thanks!
@@nicholasantidormi6238 After reading the feedback, I agree. I think your recommendation is something like: gist.github.com/lmiller1990/26eb3c2d76eb8c122a0012c1e47dc15e ?
@@31redorange08 it's simulating an network call, imagine some fetch code was used here, you would want to wait for the response from the server by returning a promise.
I did something similar on a project, but in a distributed environment. I have an in-memory object cache where values are being retrieved. It then listens to feature flag changes through redis, and updates the local in-memory cache. This made it faster because you’ll always get the latest changes without having the call the remote database all the time
Interesting - what was the use case for in memory, real time feature flags? What kind of feature did you want to turn on/off in a real time fashion for a given user?
Nice video and best explanation. But, Why to use another npm package for a small problem. Simply we can memorize the promised results. function memoize(fn) { const cache = new Map() return (arg) => { if (!cache.has(arg)) cache.set(arg, fn(arg)) return cache.get(arg) } }
Just store the Promise object directly. let promise; async function getFeatureFlag() { promise ??= getAllFeatures(); const features = await promise; // profit }
Yes - this is a lot better, I over-engineered this. Check the pinned comment! Happy to own a less than ideal answer, this is how we learn. The interviewer pointed out the deferred promise I recommended was over-engineered, which I'd agree with - no need to be able to resolve/reject outside the function call.
You are correct, there is no point in this scenario. I don't have a good reason for using pDefer here, other than I used it recently and it was fresh in my mind. See the pinned comment for a discussion.
I'll just share it, this was Atlassian, most likely a lot of people go back and forth between the two! I'm guessing this question has been used at a lot of places.
This works only for a single feature flag? What happens when we have multiple requests for multiple feature flags? We need something like a singleton class which has a queue built in to handle batching. Calling getFeatureFlag('feature1'), getFeatureFlag('feature2') should work flawlessly. And in the instance you can build a simple cache to return the value immediately if was already fetched.
The global promise (or deferred one) accomplishes this, right? You only ever get one network request - the feature flags are cached in the resolved promise. I could be misunderstanding your comment - this should work for any number of flags.
it would be better to use lru-cache for storing multiple values and implement at least a basic scheduler mechanism, when you track the status of the feature request and not going to make multiple requests. also, it is common to have real-time feature flags, which means you have a WebSocket connection or polling these values with some delay, but it looks like this is not the case, so I assume this was a question about how to deal with cache techniques.
I'm not entirely clear on why you'd need a scheduler here. The real time feature requests isn't something I've seen before but no doubt possible! It's definitely hard to show all this knowledge in a ~45m interview. I think you hit the nail on the head - the main purpose was to discuss caching and the pros/cons of each approach.
Don't really see the value of this technique. You could have fetched the feature flag object in one call and wrote a second function that extracts the value of single feature flag using the key. In a frontend app, this is usually done on login and the object is stored in local storage.
Hi! That's definitely a valid approach. As an interviewed, I might ask: what if we want to store a feature flag in the database so each user gets the same feature flagged experience regardless of device, browser, etc? I'd say there is no right answer, it'll always depend. I agree with your approach, too, simple is good!
RxJS is a very great tool, although I have found it can be difficult to debug large systems built using RxJS exclusively. It seems to work great when combined with another too, like MobX, React etc.
Only makes sense to use this p-defer package if you are going to reject or resolve the value outside the promise no?
Agree, I think you can use the variable to store the promise directly.
Another little improvement could be awaiting the promise instead of using .then, just for consistency, I'm not a big fan of mixing async/await with then (but It is just a personal preference).
This is a good point, this whole thing could be simplified to something like this
gist.github.com/lmiller1990/26eb3c2d76eb8c122a0012c1e47dc15e
p-defer package can be useful if you need to resolve/reject after the call for whatever reason, but in this situation it's not really necessary.
After thinking this through, I don't think p-defer really makes sense in this explanation. I will add a comment to this meaning.
I will leave the video as-is, happy to own this oversight and take it as a learning experience. Thanks!
@@nicholasantidormi6238 After reading the feedback, I agree. I think your recommendation is something like: gist.github.com/lmiller1990/26eb3c2d76eb8c122a0012c1e47dc15e ?
@@LachlanMillerWhy do you wrap fetchAllFeatures() inside another promise?
@@31redorange08 it's simulating an network call, imagine some fetch code was used here, you would want to wait for the response from the server by returning a promise.
I did something similar on a project, but in a distributed environment. I have an in-memory object cache where values are being retrieved. It then listens to feature flag changes through redis, and updates the local in-memory cache. This made it faster because you’ll always get the latest changes without having the call the remote database all the time
Interesting - what was the use case for in memory, real time feature flags? What kind of feature did you want to turn on/off in a real time fashion for a given user?
Nice video and best explanation.
But, Why to use another npm package for a small problem. Simply we can memorize the promised results.
function memoize(fn) {
const cache = new Map()
return (arg) => {
if (!cache.has(arg)) cache.set(arg, fn(arg))
return cache.get(arg)
}
}
Thanks for the comment. Sure, this works too. Both fine!
Just store the Promise object directly.
let promise;
async function getFeatureFlag() {
promise ??= getAllFeatures();
const features = await promise;
// profit
}
Yes - this is a lot better, I over-engineered this. Check the pinned comment!
Happy to own a less than ideal answer, this is how we learn. The interviewer pointed out the deferred promise I recommended was over-engineered, which I'd agree with - no need to be able to resolve/reject outside the function call.
I do not see any reason for using pdeffer in your example .
why do you just keep the promise instance and `.then ()` into it ?
You are correct, there is no point in this scenario. I don't have a good reason for using pDefer here, other than I used it recently and it was fresh in my mind. See the pinned comment for a discussion.
This sounds a lot like an interview I had at canva a few years ago
I'll just share it, this was Atlassian, most likely a lot of people go back and forth between the two! I'm guessing this question has been used at a lot of places.
This works only for a single feature flag? What happens when we have multiple requests for multiple feature flags? We need something like a singleton class which has a queue built in to handle batching. Calling getFeatureFlag('feature1'), getFeatureFlag('feature2') should work flawlessly. And in the instance you can build a simple cache to return the value immediately if was already fetched.
The global promise (or deferred one) accomplishes this, right? You only ever get one network request - the feature flags are cached in the resolved promise. I could be misunderstanding your comment - this should work for any number of flags.
Good video as always, thank you
My pleasure!
it would be better to use lru-cache for storing multiple values and implement at least a basic scheduler mechanism, when you track the status of the feature request and not going to make multiple requests. also, it is common to have real-time feature flags, which means you have a WebSocket connection or polling these values with some delay, but it looks like this is not the case, so I assume this was a question about how to deal with cache techniques.
I'm not entirely clear on why you'd need a scheduler here. The real time feature requests isn't something I've seen before but no doubt possible!
It's definitely hard to show all this knowledge in a ~45m interview. I think you hit the nail on the head - the main purpose was to discuss caching and the pros/cons of each approach.
Don't really see the value of this technique. You could have fetched the feature flag object in one call and wrote a second function that extracts the value of single feature flag using the key. In a frontend app, this is usually done on login and the object is stored in local storage.
Hi! That's definitely a valid approach. As an interviewed, I might ask: what if we want to store a feature flag in the database so each user gets the same feature flagged experience regardless of device, browser, etc?
I'd say there is no right answer, it'll always depend. I agree with your approach, too, simple is good!
Why Vim???
I like to use Vs Code with Vim keybindings, that's just my preferred combo.
In real world scenarios to beautifully handle asynchronous calls I would suggest using some reactive programming lib, like RxJS
RxJS is a very great tool, although I have found it can be difficult to debug large systems built using RxJS exclusively. It seems to work great when combined with another too, like MobX, React etc.
Nice video ❤
However you don’t need a deferred promise for this. I’ll be happy to edit the code for you if you post a gist 🌹🫰🏻
Heya, thanks for the comment, we discussed this already in the pinned comment
@@LachlanMiller I see it now, Perfect 🌹