【问题标题】:How do I convert a callback to a generator?如何将回调转换为生成器?
【发布时间】:2018-07-09 10:54:57
【问题描述】:

考虑以下代码:

export function* listen(channel, event, action) {
    yield call(
        [LaravelEchoManager, LaravelEchoManager.registerListener],
        channel,
        event,
        (data) => {
            // yield data;
        },
    );
}

LaravelEchoManager.registerListener 方法为给定频道和给定事件注册一个事件监听器,并为收到的每条消息调用回调(data) => { ... }

如何生成接收到的数据?

【问题讨论】:

  • 你不能。只有registerListener 返回了一个生成器(我怀疑它确实如此),这才有可能。想一想:生成器将数据返回给它的调用者。但是你不是回调的调用者,其他一些代码是。
  • 这对我来说很有意义。目前,我正在尝试使用 Promise 解决方法,其中解决方法存储在 Promise 解析器之外,以便我可以在回调中调用它们。

标签: ecmascript-6 generator redux-saga


【解决方案1】:

你可以用这种伎俩作弊:

let received = [];
let active; // set to false to stop listening
export function* listen(channel, event, action) {
    call(
        [LaravelEchoManager, LaravelEchoManager.registerListener],
        channel,
        event,
        (data) => {received[received.length] = data},
    );
    active = true; // start linstening
    while(active){
        while(received.length <= 0); // active wait
        yield received.shift();
    }
}

它回答了这个问题,但我真的不建议做这种事情。
也许你必须找到另一种方法来完成你的任务。

【讨论】:

  • 这行不通。 while(received.length &lt;= 0); 正在阻塞。数组中不能添加任何内容。
  • 啊,你是对的。如果您没有多线程进程,它将永远无法工作。
【解决方案2】:

嗯,你可以,但你必须yield 别的东西。例如一个承诺:

export function* listen(channel, event, action) {
  yield call(() => new Promise(done => {
    LaravelEchoManager.registerListener(
      channel,
      event,
      (data) => {
        done(data);
      }
    );
  }));    
}

【讨论】:

    猜你喜欢
    • 2015-05-30
    • 2015-06-24
    • 2018-11-24
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    相关资源
    最近更新 更多