function* bankAccount() {
let balance = 0;
while (balance >= 0) {
balance = yield balance;
}
return 'bankrupt! ';
}
let userAccount = bankAccount();
console.log(userAccount.next());
console.log(userAccount.next(10));
console.log(userAccount.next(-15));
...this code works - I've run it and after the third call of next(), it returns bankrupt - but why? Surely when next() is called the third time, the loop will check the balance (which will still be 10 at that point), and then add -15 to the balance, and yield out -5...leaving the next iteration to yield bankrupt.
But thats obviously not the case, the balance seems to be updated with the yield value before the loop checks the current balance, but if that line of code is running first, then why is the loop running at all? wouldn't it just be yielding out the updated balance instantly?...so, which code is being run when?
CodePudding user response:
Order of operations:
let balance = 0;
while (balance >= 0) {
- balance is 0 hereyield balance
- yields 0balance = <value passed to next = 10>
- balance is 10 after thatwhile (balance >= 0) {
- balance is 10yield balance
- yields 10balance = <value passed to next = -5>
- balance is -5 after thatwhile (balance >= 0) {
- balance is -5 so breakreturn 'bankrupt! ';
function* bankAccount() {
let balance = 0;
while (balance >= 0) {
balance = yield balance;
console.log('inside loop', balance)
}
console.log('after loop', balance)
return 'bankrupt! ';
}
let userAccount = bankAccount();
userAccount.next();
userAccount.next(10);
userAccount.next(-15);
CodePudding user response:
Surely when next() is called the third time, the loop will check the balance (which will still be 10 at that point), and then add -15 to the balance, and yield out -5.
This is nearly all correct. The biggest problem with it is that (as @Bergi correctly points out in the comments), the adding of -15 happens before the check. Therefore the conclusion:
and yield out -5
is wrong.
When -15 is added to the balance, which happens on this line when you called next
with the -15 argument:
balance = yield balance;
balance
becomes -5, as you so rightly observe. So the next statement execute is the loop check itself. balance >= 0
is no longer true, so it doesn't loop again, and moves on to the final "bankrupt"
yield - exactly as you've observed.
Perhaps your confusion is over how the next
calls and yield
s line up. So here's a quick summary:
- the first
.next()
call advanced the code to the firstbalance = yield balance;
, wherebalance
is 0. That's what's yielded, and the code awaits your next call to see what's added tobalance
. - then you call
.next(10)
, so10
gets added tobalance
. It reaches that line again, so10
is yielded, and again the generator waits to see what you give it next. - then you call
.next(-15)
, which yields the10
value. As observed above, the nextyield
is outside the loop because balance is now -5 and the loop therefore does not continue
CodePudding user response:
It is about how yield works, you can read in depth here.
In your example the yield
keyword causes the function generator to stop before the balance is increased, the following .next()
call will increase the value, so in reality the loop goes as follows:
1st call -> balance is 0 as defined, we enter the while loop, but stop before the balance increase by yielding the current balance
value
2nd call -> the yield
expression results in 10
, the balance is increased to 10, only now the first iteration is complete, we enter the loop again, but stop before balance increase by yielding the current balance
value
3rd call -> the yield
expression results in -15
, the balance becomes -5, the while condition is not valid anymore