3 ms·
Since booleans can't be awaited until their state is negated/toggled, I'd say a lock that works like a lock is needed.
by nitely 7y ago
Since booleans can't be awaited until their state is negated/toggled, I'd say a lock that works like a lock is needed.
- wayneftw 7y agoSo use a Promise like a lock then. If it exists, wait on it. If not create one… Of course you don’t need to use the existence of a Promise as your Boolean in this case. You can simply use the Boolean state in addition to the Promise because your code is not going to yield while atomically setting one Boolean variable.
- nitely 7y agoThat would unblock all coroutines waiting for the promise, instead of just the first one. It's not that trivial, that's the point.
- esprehn 7y agoFor queued ordering instead of unblocking everyone at once you can reassign the Promise. let lock = Promise.resolve() const wait = (callback) => lock = lock.then(() => callback()); Until the callback resolves the lock is held, so you can do: wait(async () => { await step1(); await step2(); // release the lock. });
- nitely 7y agoIf the callback throws an error, none of the awaiting coroutines will run, and adding a catch would break the callback error propagation.
- wayneftw 7y agoYes, but he was giving the simplest implementation for the sake of brevity. Also, nobody said that we need callback error propagation in a priority queue to act the same exact way that callback error propagation works in a straight promise chain... but if you just want to reject all waiters in case of an error, you can do that. Take a look at sindresorhus' p-queue project - https://github.com/sindresorhus/p-queue https://github.com/sindresorhus/p-queue - which is about 40 lines of code that take care of queueing exactly the way you want. And it's easy to modify if you want to reject the whole queue in case of an error, which is something that I've done myself in the past. You can see them discussing the possibility of that feature right here - https://github.com/sindresorhus/p-queue/issues/29 https://github.com/sindresorhus/p-queue/issues/29 Long story short: Your problem is with ordering, not locking.
- nitely 7y agoEven the original solution is a lot more complex than just checking some primitive value. A lock is still needed when doing concurrency on a single thread, which is the point I'm making anyway. > Long story short: Your problem is with ordering, not locking. Look up the definition of a concurrency lock.
- wayneftw 7y agoYou moved the goal posts on me. But the solution for your next scenario is actually pretty trivial though isn’t it? You don’t really need what you call locking in a single-threaded world. You just need a state machine.
- nitely 7y agoNo, I didn't. That's how a lock works. Only one coroutine (or thread) is allowed to hold it at a time while the others must await their turn. A state machine is a lot more than a boolean variable.
- wayneftw 7y agoBoth of your statements are incorrect. Locks are an abstract concept that have many different behaviors. In a multi-threaded world (not JS) a certain type of synchronization lock, such as a single-writer/multiple-reader locking mechanism would specifically allow you to unblock all waiting coroutines. Another type of lock might only allow the first waiter to unblock. There simply is no concurrency in JS though, so there is no need for locking. There is no way that you would ever "unblock all coroutines waiting for the promise" because you just can't run more than 1 coroutine at a time. So your problem is with ordering, not concurrency and locks are a solution for concurrency. And the simplest state machine is a boolean variable. Anyway, I guess if you still disagree then you can go and ask the people who build JS engines why they don't want to add locks. Maybe ask the v8 team - they add stuff that isn't in the spec all the time and they haven't seen a big need for this, so they must know the answer...
- nitely 7y agoFirst look up the definition of a lock and mutual exclusion. There are two types of basic locks: mutexes and semaphores. Both keep two threads or coroutines from executing a block of code/instructions at the same time, and both work in a similar way I already described. > There simply is no concurrency in JS though, There is no parallelism in JS (well there is with workers now), concurrency is not parallelism.