【问题标题】:How to pause a Javascript asynchronous function without setTimeout?如何在没有 setTimeout 的情况下暂停 Javascript 异步函数?
【发布时间】:2017-07-25 07:59:33
【问题描述】:

我有一个检查数据库中是否存在令牌的函数。问题是返回 bool 值需要一些时间,我需要暂停函数,以便函数意识到令牌已存在并再次运行查询。

const registerToken = dispatch => {
  var tokenExisted = null
  do {
    let token = generateRandomToken();
    firebase.database().ref(`/Token`).orderByChild("token").equalTo(token).once("value", snapshot => { // check whether token exists
      if (!snapshot.val()) {  // if token not exist
        token = false;
        // register token to firebase
      } else {
        token = true; // continue the loop to generate a new token and query again
      }
    })
  } while (tokenExisted === true);
}

我的设置基本上是一个 do-while 循环,当函数第一次被调用时 tokenExisted = null,然后将生成一个随机的 4 位令牌,并将一个查询发送到 firebase 并验证它是否存在令牌。

如果令牌已经存在,那么tokenExisted = true。我希望它会执行分配,但 Javascript 的单线程性质将在查询返回任何内容之前到达循环的末尾。

我想使用setTimeout 并定期在tokenExisted = null 时添加一些少量时间以进行安全防护,以便该函数始终在查询函数返回任何内容时捕获。

有没有人有更好的方法来实现同样的目标?

【问题讨论】:

  • 完全错误的异步代码方法。在异步调用的回调中,您要么满意,要么触发另一个异步调用。你不能在这里使用同步的do..while
  • 更不用说你不能暂停Javascript

标签: javascript reactjs firebase firebase-realtime-database logic


【解决方案1】:

您可能希望递归地调用函数本身。

const registerToken = dispatch => {
  let token = generateRandomToken();
  const tokenObjectRef = firebase.database().ref(`/Token`);

  tokenObjectRef.orderByChild("token").equalTo(token).once("value")
    .then(snapshot => {
      if (!snapshot.val()) {
        // success!
      } else {
        registerToken(dispatch) // call itself again
      }
    })
    .catch(error => {} ))
}

逻辑是令牌将在每次新迭代期间刷新,如果过程失败并且需要新查询(如果这是您需要的话)。

注意:避免在async 逻辑中使用do-while。提前计划好,因为你可能会遇到很多逻辑错误,而且很难追踪。

【讨论】:

    【解决方案2】:

    递归调用函数。

    function get_token_then(callback_when_token_found) {
        firebase.database().etc.etc(function (data) {
            if (data == what_you_want) {
                callback_when_token_found(data);
            } else {
                // You might want to wrap this in setTimeout in order to throttle your database calls
                get_token_then(callback_when_token_found);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-17
      • 2017-05-27
      • 1970-01-01
      • 2019-12-16
      • 2011-03-27
      • 2011-04-27
      • 2017-03-05
      • 1970-01-01
      相关资源
      最近更新 更多