Возможно ли реализовать функции, которые используют неблокирующее setTimeout синхронно? - PullRequest
2 голосов
/ 20 февраля 2020

Интересно, можно ли синхронно называть эти 2 IIF, чтобы они в конце производили что-то подобное?

######
#####
####
###
##
#
#
##
###
####
#####
###### ? 

функции, указанные ниже, делают запись журнала с задержкой. Идея состоит в том, чтобы консоль журнала с некоторой задержкой строка за строкой.

 (function whileLoop(n) {
        setTimeout(function () {
            let hashArr = Array.apply(null, Array(n)).map(() => {
                return hashSymbol
            });
            console.log(hashArr);
            if (--n) whileLoop(n);
        }, 2000)
    })(6);

    (function whileLoop(n, m) {
        setTimeout(function () {
            let hashArr = Array.apply(null, Array(n)).map(() => {
                return hashSymbol
            });
            console.log(hashArr);
            if (n < m) {
                ++n;
                whileLoop(n, m);
            }
        }, 2000)
    })(1, 6);

Ответы [ 3 ]

2 голосов
/ 20 февраля 2020

Чтобы вы могли отобразить его один за другим, вам нужно использовать async await. Пожалуйста, проверьте здесь: https://javascript.info/async-await

 const row = 6;
    (async() => {
   for (let r = 1;r < row * 2; r++) {
     await displayAsync('#'.repeat((r >= 7 ? (r % 6) : row - r ) + 1));
   }
})();

function displayAsync(str) {
   return new Promise((resolve, reject) => {
      setTimeout(()=> {
       console.log(str);
       resolve(null); 
      }, 1000);
   });
}
1 голос
/ 20 февраля 2020

Типичным способом обработки порядка выполнения двух разных асинхронных операций является использование обещаний.

var d = $.Deferred();

(function whileLoop(n) {
  setTimeout(function () {
    let hashArr = Array.apply(null, Array(n)).map(() => {
      return '#'
    });
    console.log(hashArr);
    if (--n) whileLoop(n);
    else d.resolve();
  }, 2000)
})(6);

d.then(function() {
  (function whileLoop(n, m) {
    setTimeout(function () {
      let hashArr = Array.apply(null, Array(n)).map(() => {
        return '#'
      });
      console.log(hashArr);
      if (n < m) {
        ++n;
        whileLoop(n, m);
      }
    }, 2000)
  })(1, 6);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
0 голосов
/ 20 февраля 2020

Вы почти у цели. Я вижу, что вы понимаете, что рекурсивный вызов setTimeout эмулирует некоторое время l oop асинхронно. И я вижу, что вы понимаете, как решить, когда продолжать «l oop», а когда останавливаться:

if (--n) whileLoop(n);

Вам просто нужно понять, что l oop заканчивается, когда if условие ложное. Таким образом, чтобы запустить второе время, пока l oop просто запустите его в else:

if (--n) {
    whileLoop(n);
}
else {
    whileLoop2(1,6);
}

Есть несколько последствий этого:

  1. Второе whileLoop должен быть переписан в НЕ быть IIFE - это должна быть обычная функция, вызываемая в конце первого whileLoop, как указано выше.

  2. Вы не можете повторно использовать имя whileLoop для обеих функций. Чтобы дифференцировать функции, вы должны переименовать либо первую, либо вторую функции «l oop».

При этом сохраняется ваш текущий лог c, требующий изменения только 4 строк, чтобы получить поведение, которое вы хотите.

...