2010-02-19 13 views
5

Bueno, el título del kindof dice lo que necesito. Porque en los tiempos de espera de Javascript asincrónicos, necesito saber cuándo algo se convierte en realidad. No quiero busyloop.javascript, espera a que algo sea cierto, ejecuta la acción

ocurrió:

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

¿Es bueno Javascript o puedo hacer mejor?

+0

¿Cuál es el predicado? – SLaks

+0

@predicate es función, la acción también es función – zaharpopov

+0

El predicado es la condición cuando eso tiene que ser cierto antes de que se llame a la acción. ** ==> ** Me parece bien. – AxelEckenberger

Respuesta

0

Es bastante decente, si es bastante fácil de leer y funciona bien, en general es bueno javascript.

En cuanto a rendimiento, generalmente es mejor llamar a la función siempre que ocurra lo que esté configurado en verdadero. Por lo tanto, en cualquier función que se ejecute para hacer que predicate() sea verdadero, simplemente puede llamar al action() al final. Pero estoy seguro de que eso es lo que hubieras hecho si pudieras, ¿verdad?

También podría utilizar el uso de una devolución de llamada, donde registra una función javascript para una variable particular o argumento de función y cuando se ejecuta la función ejecuta cualquier función que se haya establecido en la variable de devolución de llamada.

-1

si su predicado que hacerse realidad cuando un cambio de variable, aquí es otra solución:

decir que queremos log 'hermano mayor le está mirando' cuando el valor del objeto a convertirse 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; 

Puede probar este ejemplo en firefox

+1

¿Qué es get and set? es este javascript estándar? – zaharpopov

+1

Getters y setters no funcionarán en todas las implementaciones de javascript. –

+0

esto no funcionará menos tiene instalado Firebug y abierto. (porque está usando la consola) – Samuel

6

Dependiendo de cuál sea el predicado, es posible que pueda adaptar su problema a una implementación del observer pattern. Hace un tiempo escribí una publicación en el blog sobre creating JavaScript objects with observable properties. Realmente depende de lo que el predicado es , pero esto podría conseguir que la mayor parte del camino con el código como este:

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

Por supuesto, esto podría ser excesiva para tu ejemplo. Ya que nunca aparece en la lista explícitamente (nota: No soy un muy buen blogger), aquí está el código completo necesario para hacer este trabajo:

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; 
}; 

Mis objetos observables hacen uso interno de un (la función createMediator) Marco concurso completo pequeña Escribí una vez para un proyecto. (Antes de realizando eventos personalizados compatibles con jQuery. D'oh!) De nuevo, esto puede ser excesivo o no para su necesidad, pero pensé que era un hack divertido. ¡Disfrutar!

+0

Ahora que veo este código nuevamente, me gustaría poder escribir 'observable.propToWatch.observe (function() {...})'. Oh bien. Tal vez pueda retocarlo un poco más en el futuro. –

Cuestiones relacionadas