2017 — 2021 update
Since 2009 when this question was asked, JavaScript has evolved significantly. All other answers are now obsolete or overly complicated. Here is the current best practice:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
console.log('Taking a break...');
await sleep(2000);
console.log('Two seconds later, showing sleep in a loop...');
// Sleep in loop
for (let i = 0; i < 5; i++) {
if (i === 3)
await sleep(2000);
console.log(i);
}
}
demo();
This is it. await sleep(<duration>)
.
Or as a one-liner:
await new Promise(r => setTimeout(r, 2000));
Note that,
await
can only be executed in functions prefixed with the async
keyword, or at the top level of your script in an increasing number of environments.
await
only pauses the current async
function. This means it's not blocking the execution of the rest of the script, which is what you want in the vast majority of the cases. If you do want a blocking construct, see this answer using Atomics
.wait
, but note that most browsers will not allow it on the browser's main thread.
Two new JavaScript features (as of 2017) helped write this "sleep" function:
Compatibility
If for some weird reason you're using Node older than 7 (which has reached end of life), or are targeting old browsers, async
/await
can still be used via Babel (a tool that will transpile JavaScript + new features into plain old JavaScript), with the transform-async-to-generator
plugin.
The pseudovariables are only available in the context of data binding. The view model itself ideally should not know about or have any dependencies on the view that is displaying it.
So, when adding computed observables in the view model, you have no knowledge of how it will be bound (like what is going to be $root). A view model or part of a view model could even be bound separately to multiple areas of the page at different levels, so the pseudo-variables would be different depending on the element that you are starting with.
It depends on what you are trying to accomplish, but if you want your child to have an isSelected
computed observable that indicates whether this item is the same as the selected item on the parent view model, then you will need to find a way to make the parent available to the child.
One option is to pass the parent into the constructor function of your child. You do not even need to add the pointer to the parent as a property of the child and can just use it in your computed observable directly.
Something like:
var Item = function(name, parent) {
this.name = ko.observable(name);
this.isSelected = ko.computed(function() {
return this === parent.selectedItem();
}, this);
};
var ViewModel = function() {
this.selectedItem = ko.observable();
this.items = ko.observableArray([
new Item("one", this),
new Item("two", this),
new Item("three", this)
]);
};
Sample here: http://jsfiddle.net/rniemeyer/BuH7N/
If all you care about is the selected status, then you can tweak it to pass a reference to the selectedItem
observable to the child constructor like: http://jsfiddle.net/rniemeyer/R5MtC/
If your parent view model is stored in a global variable, then you could consider not passing it to the child and using it directly like: http://jsfiddle.net/rniemeyer/3drUL/. I prefer to pass the reference to the child though.
Best Answer
I would consider a getter if you are using TypeScript. You could also make your Component use ChangeDetectionStrategy.OnPush to make sure the binding is only evaluated if one of the properties changed. Here is a Plunker: https://plnkr.co/edit/PjcgmFCDj8UvBR7wRJs2?p=preview