How to check if condition for 5 seconds in Javascript

后端 未结 2 543
自闭症患者
自闭症患者 2021-01-17 05:09

How to check an if condition for 5 seconds? This if condition should be true for 5 seconds to execute its code.

function checkcodition() {         


        
相关标签:
2条回答
  • 2021-01-17 05:34

    You can use MutationObservers to handle changes of a given element.

    Update: Seeing your previous question, I changed my answer, as I think I misjudged what you wanted to do. It now does the following:

    • wait for an element's innerText to transition from '0' to '1' and if it stays '1' for 5 seconds, trigger the callback

    // randomly change values
    (function valUpdate() {
      Array.from(document.querySelectorAll('p')).forEach((el) => {
        el.innerText = Math.round(Math.random());
      });
    
      setTimeout(valUpdate, 1000);
    })();
    
    
    // helpers
    
    const onMutation = (target, cb, config = {childList: true, characterData: true, subtree: true}) => {
      const observer = new MutationObserver((mutations) => {
        cb(target, observer.disconnect.bind(observer), mutations);
      });
    
      observer.observe(target, config);
    };
    
    const onChange = (selector) => (target, cb) => {
      let prev = selector(target);
    
      onMutation(target, (_, disconnect) => {
        const current = selector(target);
    
        if (prev !== current) {
          cb(prev, current, target, disconnect);
        }
    
        prev = current;
      });
    };
    
    const ifStatic = (decider) => (time, cb) => {
      let to;
    
      return (...args) => {
        if (decider(...args)) {
          to = setTimeout(cb, time, ...args);
        } else {
          clearTimeout(to);
        }
      };
    };
    
    // setup
    
    const onInnerTextChange = onChange((el) => el.innerText);
    const ifValidFor = ifStatic((prev, current) => prev === '0' && current === '1');
    const sendSms = (message, stop = false) => (prev, current, el, done) => {
      console.log('Sending SMS for:', el.id, 'Message', message);
      stop && done();
    };
    
    onInnerTextChange(document.querySelector('#demo1'), ifValidFor(5000, sendSms('Message 1')));
    onInnerTextChange(document.querySelector('#demo2'), ifValidFor(5000, sendSms('Message 2', true)));
    onInnerTextChange(document.querySelector('#demo3'), ifValidFor(5000, sendSms('Message 3', true)));
    <h2>Test SMS Triggers</h2>
    <p id="demo1">0</p>
    <p id="demo2">0</p>
    <p id="demo3">0</p>


    Note that, depending on how the node is changed, you might need to fiddle with the MutationObserverInit configuration. Above I used:

    { childList: true, characterData: true, subtree: true }
    

    You'll need at least IE11 for this to work. If you need to support older versions, then there might be other solutions, though I dare not utter them. ;)



    For the sake of showing how simple this could be done with better tools, here's a rxjs version:

    const { Observable } = Rx;
    
    const fromMutation = (target, config) => new Observable((observer) => {
      const mutationObserver = new MutationObserver((mutations) => {
        observer.next(mutations);
      });
    
      mutationObserver.observe(target, config);
    
      return () => {
        mutationObserver.disconnect();
      };
    });
    
    const sendSmsAfter = (delay) => (el) => fromMutation(el, {characterData: true, childList: true, subtree: true})
      .map(() => el.innerText)
      .startWith(el.innerText)
      .distinctUntilChanged()
      .pairwise()
      .switchMap(([prev, current]) => prev === '0' && current === '1'
        ? Observable.of(el).delay(delay)
        : Observable.empty()
      )
    ;
    
    const elements = document.querySelectorAll('#demo1, #demo2, #demo3');
    
    Observable
      .from(elements)
      .mergeMap(sendSmsAfter(5000))
      .subscribe((el) => {
        console.log('sms go!', el.id);
      })
    ;
    
    Observable
      .interval(1000)
      .switchMapTo(elements)
      .subscribe((el) => {
        el.innerText = Math.round(Math.random());
      })
    ;
    <script src="https://unpkg.com/@reactivex/rxjs@^5/dist/global/Rx.min.js"></script>
    
    <h2>Test SMS Triggers</h2>
    <p id="demo1">0</p>
    <p id="demo2">0</p>
    <p id="demo3">0</p>

    0 讨论(0)
  • 2021-01-17 05:35

    You should use browser APIs setTimeout function.

    This example will only check the condition AFTER five seconds, not DURING five second interval. If you want to make sure the condition stays true during whole interval, you should probably implement some onValueChange() type event.

    function checkCodition() {
        let a, b;
        setTimeout(() => {
            if (a === 0 && b === 1) {
                console.log(" This line shoud display after 5 seconds");
            }
        }, 5000);
    }
    

    Additional info:

    You should use tripple equality sign ===, use let instead of var and camelCase insted of lowercase for function names.

    0 讨论(0)
提交回复
热议问题