Javascript 生成器:理解它们

2024-04-26

我很确定我对生成器的理解本质上是被破坏的。所有在线资源似乎都是冲突的,这导致了极其困难和令人困惑的学习体验。

据我了解,yield关键字使当前正在执行的代码块能够等待一个值而不是抛出要在回调内执行的剩余代码。因此,正如大多数教程所指出的,您可以使用它:

(function *() {
     // Wait until users have be got and put into value of `results`
     var results = yield db.get("users");
     // And continue
     view.display(results);
})();

代替:

db.get("user", function(results) {
    view.display(results);
});

是的,这一切都很好,直到我尝试编写自己的生成器。我遇到了几个麻烦:

  • 我上面的第一个示例代码将不会运行,因为没有什么可以迭代生成器,对吗?一些更高的存在必须调用.next某处,对吗?
  • 整个 API 必须重写到 I/O 调用才能支持生成器,对吗?
  • 据我收集的信息,yield似乎代表等待值最常见的用例,而在实现部分(阅读:返回值到/内部db.get) yield似乎代表将此值发送回当前等待的块以恢复执行.

举个例子:

function *fn() {
    yield 1;
    yield "a";
}

var gen = fn();
gen.next(); // 1
gen.next(); // "a";

yield在这种情况下,是将值发送回而不是等待结果。在上面的第一个示例中,它等待来自db.get并且恢复执行而不是“返回”或发回一个值。如果db.get情况确实如此,这不是本质上同步的吗?我的意思是,这不是完全一样吗:

(function() {
     //Wait for the results
    var results = fs.readFileSync("users.txt");
    // Use results
    view.display(results);
})();

不幸的是,如果从这个问题可以清楚地看出(可能是唯一清楚的),那就是我不理解生成器。希望我能在这里得到一些见解。


TL;DR:生成器的本质是控制代码执行的暂停。

对于生成器本身,您可以参考this http://wiki.ecmascript.org/doku.php?id=harmony%3agenerators.

总而言之,您应该区分三个组件: 1. 生成器功能 2. 发电机 3. 生成结果

生成器函数很简单function头上有星星并且(可选)yield在它的身体里。

function *generator() {
  console.log('Start!');
  var i = 0;
  while (true) {
    if (i < 3)
      yield i++;
  }
}

var gen = generator();
// nothing happens here!!

生成器函数本身不执行任何操作,只是返回一个生成器,在上面的情况下,gen。 这里没有控制台输出,因为只有在返回之后发电机's next方法被称为主体生成器函数会跑。 Generator 有几个方法,其中最重要的一个是next. next运行代码并返回生成器结果.

var ret = gen.next();
// Start!
console.log(ret);
// {value: 0, done: false}

ret上面是生成器结果。它有两个属性:value,你产生的价值生成器函数, and done,一个标志,指示是否生成器函数 return.

console.log(gen.next());
// {value: 1, done: false}
console.log(gen.next());
// {value: 2, done: false}
console.log(gen.next());
// {value: undefined, done: true}

此时,没有人会指望你了解generator,至少不会期望你了解generator的异步电源。

简单来说,generator有两个特点:

  • 我们可以选择跳出函数并让外部代码决定何时跳回函数。
  • 异步调用的控制可以在代码之外完成

在代码中,yield跳转到函数之外,并且next(val)跳回函数并将值传递回函数。 外部代码可以处理异步调用并决定切换到您自己的代码的适当时间。

再看一下示例:

var gen = generator();
console.log('generated generator');
console.log(gen.next().value);
// mock long long processing
setTimeout(function() {
  console.log(gen.next().value);
  console.log('Execute after timer fire');
}, 1000);
console.log('Execute after timer set');

/* result:
    generated generator
    start
    0
    Execute after timer set
    1
    Execute after timer fire
*/

看?生成器函数本身不处理回调。外部代码确实如此。

基地就在这里。您可以详细说明此代码以支持完全异步性,同时保持生成器功能如同步功能。

例如,假设geturl是一个异步调用,返回一个promise目的。你可以写var html = yield getUrl('www.stackoverflow.com');这会跳转到您的代码之外。外部代码会执行以下操作:

var ret = gen.next();
ret.then(function (fetchedHTML) {
  // jumps back to your generator function
  // and assign fetchHTML to html in your code
  gen.next(fetchedHTML);
});

更完整的指南,请参阅this http://blogs.atlassian.com/2013/11/harmony-generators-and-promises-for-node-js-async-fun-and-profit/。 和存储库一样co https://github.com/visionmedia/co, galaxy https://github.com/bjouhier/galaxy, suspend https://github.com/jmar777/suspend等等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript 生成器:理解它们 的相关文章

随机推荐

  • 使用二进制遮罩遮罩 RGB 图像

    我在 MATLAB 中读入了一个 RGB 图像 M x N x 3 矩阵 我还有一个图像的二进制掩码 M x N 矩阵 对于某些感兴趣的区域来说它只是 0 而其他地方都是 1 我正在尝试找出如何使用该二进制掩码来掩蔽 RGB 图像 我尝试过
  • Android 将位图保存到 SD 卡

    我有一个按钮 我希望当我单击它时 图像会保存到 SD 卡中 或内部存储 如 htc one x 我们没有像 SD 卡这样的外部存储 这是我的代码 sd setOnClickListener new View OnClickListener
  • 我可以为我的 r 闪亮界面使用 index.html 和 ui.r 吗?

    在参照this http shiny rstudio com articles html ui html关于如何完全用 HTML 构建闪亮的应用程序 我想知道是否有任何方法可以将这种方法与传统的 ui r 方法结合使用 Reason Thi
  • Akavache 的 GetObject 在等待时挂起。知道这里出了什么问题吗?

    我有一个 Xamarin Forms 应用程序 在我的 App 类中包含以下代码 是的 这只是演示该问题的示例 public App BlobCache ApplicationName MyApp BlobCache EnsureIniti
  • Laravel 验证 - 输入必须是数组中的项目之一

    Laravel 5 中是否有内置验证器来检查值是否在我的白名单值数组中 例如 rules field name gt required in array yes no maybe There s in http laravel com do
  • 如何在测试执行之前强制使用 Spring 上下文的新版本

    我用SpringJUnit4ClassRunner用于编写集成测试 我也用 DirtiesContext对于将上下文置于损坏状态的测试 并且效果很好 但现在我有一个测试 在静态初始化器中设置一个重要的 SystemProperty 该初始化
  • 如何从电子邮件地址检索姓名

    使用javascript 我们如何从字符串中删除 gmail com或 aol com 以便只留下名称 var string email protected cdn cgi l email protection 只会是 johdoe 吗 我
  • 如何在Android Studio 1.0.0中更改logcat字体大小? [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 如何在Android Studio 1 0 0中更改logcat字体大小 我只找到了在 Android Studio 中
  • Lambda 演算和教会数字混淆

    我正在尝试了解 lambda 演算和丘奇数字的基础知识 我已经进行了大量的阅读和练习 但我似乎一直试图了解某些函数是如何工作的 我坚持的例子如下 也许有人可以解释我哪里出了问题 1 的丘奇数可以表示为 f x f x The exponen
  • 如何将 Python 中的 MS Botframework 部署到 Azure

    我一直在玩 Botframework 并尝试从 git 上传示例代码https github com Microsoft botbuilder python tree master samples EchoBot with State ht
  • 在 Mobile Safari 中重用 HTML5 音频对象

    我希望在 iPad 上的 Mobile Safari 中运行的 Web 应用程序上播放一个简短 小于 1 秒 的音频文件 以响应用户输入 同时将事件和音频播放之间的延迟降至最低 在页面重新加载之间可以多次触发播放 因此我想缓存音频文件 以下
  • Django allauth Facebook 本地开发

    我在用着Django allauth https github com pennersr django allauth对于正在开发的网站的 Facebook 身份验证 并进行了相应的设置 在 facebook 的 facebook 应用程序
  • 在 PyGTK 中,显示 PNG 文件的简单方法是什么?

    以下 PyGTK 代码在窗口中显示 PNG 文件 是否有更简单或更好的方式来显示 PNG 文件 例如使用 gtk DrawingArea 例如 如何调整文件大小 import gtk import pygtk pygtk require 2
  • 使用 datashader、holoviews 和 bokeh 进行地理映射时出现问题

    我正在尝试使用全息视图 数据着色器和散景将谷歌手机历史记录位置映射到地图上 大部分与 datashader 网站中给出的示例非常相似 但是当我这样做时 地图叠加不起作用 因为纬度 经度被破坏了 import datashader as ds
  • igraph (R) 中仅在根和终端顶点上添加标签?

    inst2 c 2 3 4 5 6 motherinst2 c 7 8 2 10 11 km c 20 30 40 25 60 df2 data frame inst2 motherinst2 df2 cbind df2 km g2 gra
  • 带有任意 AND 子句的动态 spring data jpa 存储库查询

    我在用着Spring data jpa repositories 需要提供不同字段的搜索功能 搜索前输入字段是可选的 我有 5 个字段EmployeeNumber Name Married Profession and DateOfBirt
  • java中如何销毁进程

    我写了下面的代码 要从 Java 应用程序运行 bat 文件 我使用 process exec 但蝙蝠有时可能会挂起 所以我需要为此过程设置一个超时 我启动一个新线程并在线程中新建一个进程 我在线程中设置超时 并在超时时杀死线程 但我发现超
  • 在 React 组件中使用绝对路径

    如何使用根目录中的绝对路径并更改根目录来导入组件 import Modal from project app src Components Modal import Main from Constants 我想要将根目录更改为我可以从 sr
  • 如何通过更新和多重选择将多个输入构建到我闪亮的应用程序中?

    我正在构建一个flex dashboard shiny应用程序与datatable并尝试建立两个输入作为此选择datatable每个选项都有一个 全部 选项 第一个问题是如何限制第二个选择 user 通过选择第一选择 team 然后 使用这
  • Javascript 生成器:理解它们

    我很确定我对生成器的理解本质上是被破坏的 所有在线资源似乎都是冲突的 这导致了极其困难和令人困惑的学习体验 据我了解 yield关键字使当前正在执行的代码块能够等待一个值而不是抛出要在回调内执行的剩余代码 因此 正如大多数教程所指出的 您可