javascript, wait for something to be true then run action - Stack Overflow

Well the title kindof says what I need. Because in Javascript timeouts asynchronous I need to know when

Well the title kindof says what I need. Because in Javascript timeouts asynchronous I need to know when something bees true. I don't want busyloop.

Came up with:

function do_when(predicate, action, timeout_step) {
    if (predicate()) {
        action();
    } else {
        setTimeout(do_when, timeout_step, predicate, action, timeout_step);
    }
}

Is it good Javascript or can I make better?

Well the title kindof says what I need. Because in Javascript timeouts asynchronous I need to know when something bees true. I don't want busyloop.

Came up with:

function do_when(predicate, action, timeout_step) {
    if (predicate()) {
        action();
    } else {
        setTimeout(do_when, timeout_step, predicate, action, timeout_step);
    }
}

Is it good Javascript or can I make better?

Share Improve this question asked Feb 19, 2010 at 13:33 zaharpopovzaharpopov 17.3k24 gold badges77 silver badges94 bronze badges 2
  • @predicate is function, action is also function – zaharpopov Commented Feb 19, 2010 at 13:41
  • The predicate is the condition when that has to be true before the action is called. ==> Looks sound to me. – AxelEckenberger Commented Feb 19, 2010 at 13:42
Add a ment  | 

3 Answers 3

Reset to default 6

Depending on what the predicate is, you might be able to fit your problem into an implementation of the observer pattern. A while back I wrote a blog post about creating JavaScript objects with observable properties. It really depends on what the predicate is, but this might get you most of the way there with code like this:

var observable = createObservable({ propToWatch: false });
observable.observe('propToWatch', function (oldValue, newValue) { 
    alert('propToWatch has changed from ' + oldValue + ' to ' + newValue); 
});
observable.propToWatch(true); // alert pops

Of course, this might be overkill for your example. Since it's never listed out explicitly (n.b. I am not a very good blogger), here's the plete code needed to make this work:

var createMediator = function () {
    var events = {};
    return {
        subscribe: function (eventName, callback) {
            events[eventName] = events[eventName] || [];
            events[eventName].push(callback);
        },
        publish: function (eventName) {
            var i, callbacks = events[eventName], args;
            if (callbacks) {
                args = Array.prototype.slice.call(arguments, 1);
                for (i = 0; i < callbacks.length; i++) {
                    callbacks[i].apply(null, args);
                }
            }
        }
    };
};

var createObservable = function (properties) {
    var notifier = createMediator(), createObservableProperty, observable;
    createObservableProperty = function (propName, value) {
        return function (newValue) {
            var oldValue;
            if (typeof newValue !== 'undefined' &&
                value !== newValue) {
                oldValue = value;
                value = newValue;
                notifier.publish(propName, oldValue, value);
            }
            return value;
        };
    };
    observable = {
        register: function (propName, value) {
            this[propName] = createObservableProperty(propName, value);
            this.observableProperties.push(propName);
        },
        observe: function (propName, observer) {
            notifier.subscribe(propName, observer);
        },
        observableProperties: []
    };
    for (propName in properties) {
        observable.register(propName, properties[propName]);
    }
    return observable;
};

My observable objects make use internally of a small eventing framework (the createMediator function) I wrote once for a project. (Before realizing jQuery supported custom events. D'oh!) Again, this may or may not be overkill for your need, but I thought it was a fun hack. Enjoy!

It's decent enough, if it's easy enough to read and it works just fine then it's generally good javascript.

Performance-wise, it's generally better to call the function whenever whatever is set to true happens. So in whatever function that executes to make predicate() return true, you could just call action() at the end. But I'm sure that's what you would have done if you could, right?

You could also look at using a callback, where you register a javascript function to a particular variable or function argument and when the function is run it executes whatever function was set to the callback variable.

if your predicate bee true when a variable change, here is another solution:

say we want to log 'Big brother is watching you' when value of object a bee 2.

function observable (value, condition, callback){
    this.value = value;
    this.condition = condition;
    this.callback = callback;
}

observable.prototype = {
    get value () {
        return this._value;
    },
    set value (value) {
        this._value = value;
        if (this.condition && this.callback && this.condition (value)) {
            this.callback (value);
        }
    }
};

condition = function (value) {
    console.log ('condition', value);
    return value === 2;
}

callback = function (value) {
    console.info ('Big Brother is watching you!');
}

var a = new observable (0, condition, callback);

console.log ('set value to 1');
a.value = 1;
console.log ('set value to 2');
a.value = 2;
console.log ('set value to 3');
a.value = 3;

you can try this exemple in firefox

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1741833236a4368656.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信