3 ms·
If you have code like: let x = 0; doSomethingAsync(); // does not touch x console.log(x); There's no guarantee that x will have the value 0 by the time you
by ermir 5y ago
If you have code like:
let x = 0;
doSomethingAsync(); // does not touch x
console.log(x);
There's no guarantee that x will have the value 0 by the time you get to console.log(x). The value of x might have been changed by an outside function that just happened to run between your statements. In synchronous JS this would never happen as callbacks are scheduled to run only at the end of a function, and if they change x the change will only be applied after x is printed.
The change in behavior will break a lot of existing code, since the synchronous behavior of a function is a core feature and assumption of the language.
- tines 5y agoIsn't that only really a problem with global variables? Local variables would be safe from this kind of behavior I'd think.
- protoduction 5y agoThank you for taking the time to explain :) I completely see that this will break existing code, but I don't see how this is different from the behavior of Go (where the setTimeout code would be something in a different goroutine) or Python?
- thysultan 5y agoThat is false except for the case that x is a global variable, no outside function can change the value of x, only in-scope procedures can do that.
- ermir 5y agoI guess it is true in this particular example, since 0 is a primitive and assigned by value. But what if you got it from an outside function, such as init(), and it was an object instead? Then you would have to guarantee that the return value of init() would not change between statements. In the end this shows that JS is unequipped to handle such behavior without significant changes to the core language.
- brundolf 5y ago> But what if you got it from an outside function, such as init(), and it was an object instead? Then you would have to guarantee that the return value of init() would not change between statements. Then even in a synchronous context you'd have no guarantee that it wouldn't be modified: function soSomethingSync() { window.someObj.someProp = 12; } let x = window.someObj; soSomethingSync(); console.log(x) This has nothing whatsoever to do with sync vs async. It is one of the main reasons people like immutability/functional programming. But that's its own topic.
- jayd16 5y agoYou are guaranteed that only code you call will be run. Sure you can call anything you want but the point is you have full control over what that is. If you yield execution with an await, you no opt out of that guarantee. Its a fundamental concurrency pattern used in a lot of languages, often for UI threads and such. There's a lot of information on this topic and it certainly is about async/yielding.
- thysultan 5y agoThen this is not related to async/await but regardless even then JavaScript has always had the ability to change the writability of properties such that trying to change a property in an object will yield a no-op with Object.defineProperty, and now with newer features like Object.freeze and private properties.
- jayd16 5y agoNot just globals, anything passed in or passed out, right?