【问题标题】:Call a generator function inside setInterval()在 setInterval() 中调用生成器函数
【发布时间】:2019-06-08 16:38:52
【问题描述】:

我试图在setInterval() 方法中调用生成器函数。这段代码的目的是它会定期向特定服务器查询一些数据,直到它得到一个非零响应。收到响应后,它将调用storeAddress(),这是在同一文件中定义的生成器函数。 下面的代码给了我这样的错误:

语法错误:yield 是保留字 (248:6)

注意:我正在使用 react-boilerplate 构建我的应用程序。据我通过搜索互联网可以看出,上述错误是由 babel 引发的。

  • 我试过const query = yeild call (setInterval, function(){magic code}, 10000)。这不会给出错误,但magic code 永远不会被执行。

  • 我试过const query = setInterval(function* () {magic code}, 10000),效果和上面一样。

  • 我试过const query = setInterval(yield call(function(){magic code}, 10000),效果和上面一样。

  • 我试过const query = yield call (setInterval, function(){magic code}, 10000),效果和上面一样。

  • 我在setInterval() 中尝试过storeAddress(action.payload, balance).next()。控件确实在storeAddress() 内部流动,但该函数内部也有生成器调用,它永远不会被调用。事实上,在这种情况下,storeAddress() 内部的第一次生成器调用后没有执行任何操作。

    function* callSaveNewAddress(action){
      const selectedNetwork = yield select(selectNetworkId());
      let count = 1;
      let balance = 0;
      const query = setInterval(function () {
        getAddressBalance(action.payload, selectedNetwork).then(res => 
        {return balance = res.data.mempool_balance});
    
        if(balance > 0) {
           yield call (storeAddress, action.payload, balance);
           clearInterval(query);
        } else if(count == 90) {
           clearInterval(query);
           console.log("Nothing received in 15 minutes");
        }
      }, 10000);
    }
    

那么我应该如何在像setInterval() 这样的普通函数中调用storeAddress(),它是一个生成器函数?

【问题讨论】:

  • 那么代码只需要在clearInterval() 被调用之前yield 一次。实际上这是 redux saga 的一部分,所有函数都是为此目的的生成器。将一个变为正常功能将导致更改所有 sagas。我真正需要的是创建一个延迟循环来执行相同的操作,但我需要使用生成器来完成。它不必是setInterval()。使用生成器调用进行延迟循环的任何其他方式也可以。

标签: node.js redux react-redux generator saga


【解决方案1】:
const query= function * () {
  const runner = yield call(setInterval, () => {
    getAddressBalance(action.payload, selectedNetwork).then(res => 
    {return balance = res.data.mempool_balance});

    if(balance > 0) {
       yield call (storeAddress, action.payload, balance);
       clearInterval(query);
    } else if(count == 90) {
       clearInterval(query);
       console.log("Nothing received in 15 minutes");
    }
  }, 1000);
}

尝试在调用中使用 setInterval,通过参数传递您要在其中执行的函数。

【讨论】:

  • 不,它给出了相同的SyntaxError: yield is a reserved word (252:9) 错误。我认为那是因为这里也 yield 在普通函数中被调用。我真正需要的是用生成器函数创建延迟循环的某种方法,即循环将以给定的延迟迭代,一旦满足条件yield call (storeAddress, ...arguements)将被调用。它不必是setInterval()。任何其他方式也可以。
  • 我明白了,也许这个例子可以帮助你:function * idMaker () { var index = 0; while (index console.log (gen.next ()), 1000) 你可以在setInterval中声明你要使用的生成函数,然后在这个回调中调用它方式
  • 感谢您的建议。这就是我尝试过的(在我上一个项目符号中提到的不同尝试)。奇怪的是,这种调用生成器的方式就像在控件中一样在生成器内部流动。但如果生成器本身调用其他生成器,则不会执行这些调用。例如,在我的例子中,function* storeAddress() 通过yield call (someFunction) 调用其中的其他生成器函数,在此yield 调用之前的所有内容都将被执行,但包括yield 本身在内的所有内容都不会被执行。这是一个奇怪的混乱。
猜你喜欢
  • 2021-02-11
  • 2018-11-30
  • 2020-06-22
  • 1970-01-01
  • 2017-11-14
  • 2021-12-28
  • 2018-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多