【问题标题】:Is it posible to implement functions that use non blocking setTimeout synchronically?是否可以同步实现使用非阻塞 setTimeout 的函数?
【发布时间】:2020-02-20 04:15:31
【问题描述】:

我想知道是否可以同时调用这 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);

【问题讨论】:

  • 你的意思是一个接一个?
  • 有很多方法可以做你想做的事,但基本上你有两个选择: 1. 在第一个函数完成后,使用一个带有回调函数的承诺或一些实现来调用第二个函数。 2. 在两个函数的作用域中使用一个变量来设置第二个函数的启动条件。如果没有关于您的约束的更具体信息,很难更准确。

标签: javascript asynchronous iif


【解决方案1】:

为了让你一一显示,你需要使用asyncawait。 请在此处查看: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);
   });
}

【讨论】:

    【解决方案2】:

    处理两个不同异步操作的执行顺序的典型方法是使用 Promise。

    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);
    });
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案3】:

      你快到了。我看到您了解对setTimeout 的递归调用会异步模拟while 循环。而且我看到您了解如何决定何时继续“循环”以及何时停止:

      if (--n) whileLoop(n);
      

      您只需要意识到当if 条件为假时循环结束。因此,要运行第二个 while 循环,只需在 else 中启动它:

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

      这有一些影响:

      1. 第二个 whileLoop 必须重写为 NOT 成为 IIFE - 它必须是在第一个 whileLoop 末尾调用的常规函数​​,如上所述。

      2. 您不能为这两个函数重复使用名称 whileLoop。要区分函数,您必须重命名第一个或第二个“循环”函数。

      这保留了您当前的逻辑,只需更改 4 行即可获得您想要的行为。

      【讨论】:

        猜你喜欢
        • 2020-12-07
        • 2013-05-07
        • 2018-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2013-07-20
        相关资源
        最近更新 更多