javascript - 如何从生成器函数调用的异步回调中产生 yield ?

标签 javascript node.js asynchronous generator yield

我刚刚学习node.js 生成器,我想让生成器从生成器调用的异步方法的回调中生成一个值。以下代码是我当前的示例。第一个生成器 (get_urls) 返回网站某些页面的一系列 URL。效果很好。

第二个生成器应该使用 unirest 来检索每个网页,以便生成器可以返回页面内容。但是,我不知道如何从 unirest.end() 函数的回调中产生 yield 。

可能有一些库可以更全面地执行此操作(并且具有更好的错误处理能力),但我试图了解最低级别,以便当我足够聪明地使用它们时,我可以从库中获得更多信息。

#!/usr/local/bin/node
// -*- mode: Javascript; -*-

var unirest = require( 'unirest' );

for (var url of get_urls( 'http://www.example.com/generated-page?n=1' ))
    console.log( 'Get url', url );

for (var page of get_pages( 'http://www.example.com/generated-page?n=1' ))
    console.log( 'Got page', page );

function* get_urls( url ) {
    do {
        yield url;
        var rx = url.match( /^(.*?n=)([0-9]+)$/ );
        if (rx) {
            if (rx[2] >= 3) break;
            url = rx[1] + (parseInt(rx[2]) + 1).toString( );
        }
    } while (rx);
}

function* get_pages( url ) {
    do {
// *** This is what I want to do, but it's not the right way to do it! ***
//      unirest.get( url ).end( function (rsp) { yield rsp; } );
        var rx = url.match( /^(.*?n=)([0-9]+)$/ );
        if (rx) {
            if (rx[2] >= 3) break;
            url = rx[1] + (parseInt(rx[2]) + 1).toString( );
        }
    } while (rx);
}

最佳答案

yield 只能让出直接包含它的生成器function*。因此,您无法从回调中屈服。

您可以从回调中执行的操作是解析 Promise,您的生成器函数可以生成该 Promise。

你的答案有很多无关的代码(加上为什么在有 native Fetch 等时使用 unirest),所以这里有一个示例(来 self 的 another answer ),它说明了重复产生 promise 的概念:

async function* fetchUrls() {
  let i = 0;
  while (i < 10)
    yield new Promise((resolve, reject) => {
      setTimeout(() => resolve(i++), 200);
    });
}

(async function main() {
  // for-await-of syntax
  for await (const result of fetchUrls())
    console.log(result);
}());

新的for-await-of语法自 Node v9.2 起可用,并且可以在 Node v10 或更高版本中使用,无需任何标志。

关于javascript - 如何从生成器函数调用的异步回调中产生 yield ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35308585/

相关文章:

javascript - 无法通过网页上传数据到 Parse.com

javascript - 将一组未删节的连续字符串值解析为可用的可索引键值对

javascript - AngularJS:为什么我不能使用箭头键从文本框中选择自动完成列表?

javascript - 比较 2 个对象并删除它们之间的重复键

node.js - 使用 .htaccess 的 Node.js/Gulp 的漂亮 URL?

c# - 只读 WaitHandle C#

javascript - 根据日期时间字段填充文本框。 ASP.NET C# JS

java - 使用ajax异步在表中显示servlet的列表输出

c# - 任务的执行在 C# 中使用 Task.WaitAll 挂起

javascript - 为什么node.js比apache 2.4慢这么多