rxjs 怎么使用

I loved DragonBall Z as a kid, and still love it as an adult.

我从小就爱DragonBall Z,但从小到大仍然喜欢它。

Among the ludicrous number of transformations, the original Super Saiyan remains my favorite.

在可笑的转换数量中,原始的超级赛亚人仍然是我的最爱。

Nothing quite like the original

没有什么比原来的

I’m also loving RxJS the more I level up with it, so why not combine these two for the ultimate showdown?

我越喜欢RxJS,就越喜欢RxJS,那么为什么不将两者结合起来进行最终的对决呢?

我们去超级赛亚人 (Let’s Go Super Saiyan)

With four sprite sheets and a bit of HTML, CSS, and RxJS, we can recreate this legendary transformation!

通过四个Sprite工作表以及一些HTML,CSS和RxJS,我们可以重新创建这个传奇的转换!

This is what we’ll be making. Exciting, right?! ?

这就是我们要做的。 令人兴奋,对吗? ?

建立 (Setup)

Everything’s on my GitHub.

一切都在我的GitHub上 。

cd ./wherever-you-want
git clone [https://github.com/yazeedb/dbz-rxjs](https://github.com/yazeedb/dbz-rxjs)
cd dbz-rxjs

Open index.html in your favorite browser, and the project in your favorite text editor, and you’re ready to go!

在您喜欢的浏览器中打开index.html ,然后在您喜欢的文本编辑器中打开该项目,就可以开始了!

No npm installs today ?

今天没有npm install吗?

And going forward, I’ll use the acronym “SSJ” instead of “Super Saiyan” for brevity.

为了简便起见,我将使用缩写词“ SSJ”代替“ Super Saiyan”。

训练的第一天 (First Day of Training)

You’ll notice that Goku’s already moving. Since we’re focusing on RxJS, we’ll just skim the project’s starting point.

您会注意到悟空已经在移动了。 由于我们专注于RxJS,因此我们将略过项目的起点。

Here’s the main HTML:

这是主要HTML:

<div id="root"><div id="meter-container"><span>Hold any key to POWER UP!</span><div id="meter"></div></div><div id="sprite" class="base"></div>
</div>

The bottom div has class="base", which corresponds to this CSS:

底部div具有class="base" ,它对应于以下CSS:

.base,
.ssj {width: 120px;height: 250px;animation: stand 0.8s steps(2) infinite;
}.base {background-image: url('img/goku-standing-sheet.png');
}

This sets Goku’s width, height, and standing animation.

设置悟空的宽度,高度和站立动画。

If you look at his base/ssj sprite sheets, it’s two different positions and we’re switching between them every 0.8 seconds.

如果您查看他的base / ssj Sprite表,它是两个不同的位置,我们每0.8秒切换一次。

The switching’s handled towards the bottom of style.css:

切换处理到style.css的底部:

@keyframes stand {from {background-position: 0px;}to {background-position: -255px;}
}

Same thing for power up:

上电相同:

@keyframes powerup {from {background-position: 0px;}to {background-position: -513px;}
}

We’ll cover the power up meter when we manipulate it.

在操作电表时,我们将对其进行介绍。

掌握DOM元素 (Mastering the DOM Elements)

index.html already includes RxJS@6.2.1 via CDN, so you’re covered.

index.html已经通过CDN包含RxJS@6.2.1 ,因此您已RxJS@6.2.1

In app.js, let’s capture the DOM elements we’re interested in:

app.js ,让我们捕获我们感兴趣的DOM元素:

const sprite = document.querySelector('#sprite');
const meterContainer = document.querySelector('#meter-container');
const meter = document.querySelector('#meter');

I prefer to alias document.querySelector so using it doesn’t cause me wrist pain.

我更喜欢给document.querySelector加上别名,因此使用它不会引起手腕疼痛。

const $ = document.querySelector.bind(document);**
const sprite = $('#sprite');
const meterContainer = $('#meter-container');
const meter = $('#meter');

Next, we’ll create a main function and immediately call it.

接下来,我们将创建一个main函数并立即调用它。

// ...const main = () => {// do something
};
main();

上电 (Powering Up)

Here is main’s first code snippet:

这是main的第一个代码段:

const main = () => {const { fromEvent } = rxjs;const begin = fromEvent(document, 'keydown');const end = fromEvent(document, 'keyup');
};

Goku should power up when a key is held down, and stop when that key is let go. We can use the fromEvent operator to create two observables:

按下某个键时,悟空应该上电,放开该键时应该停止。 我们可以使用fromEvent运算符来创建两个可观察对象:

  • begin: Notifies when the user presses a key down.

    begin :通知当用户按下一个键下来

  • end: Notifies whenever the user lets go of a key.

    end :在用户放开任何按键时通知。

Then we can subscribe to these emissions and act upon them. To get the power up animation, give sprite the powerup class name.

然后,我们可以订阅这些排放并对其采取行动。 要获得加电动画,请给spritepowerup类别名称。

begin.subscribe(() => {sprite.classList.add('powerup');
});

It works, but pressing a key causes him to power up forever…

可以,但是按一个键会使他永远通电……

We must also subscribe to the end observable, so we know when the key has been let go.

我们还必须订阅可观察的end ,以便我们知道何时释放密钥。

end.subscribe(() => {sprite.classList.remove('powerup');
});

Now he powers up and down at your command.

现在,他根据您的命令上下电。

建立童子军 (Building a Scouter)

Any DBZ fan has seen a scouter, the little eyewear used to track power levels (until like episode 20…).

任何DBZ粉丝都曾经看到过一个窥探者,那是用来追踪功率水平的小眼镜(直到第20集…)。

Obligatory > 9000 joke

强制性> 9000笑话

As Saiyans power up, their power level grows. Inconceivable, right?

随着赛亚人的力量上升,他们的力量水平也在增长。 不可思议吧?

We need a way to track Goku’s power level as he ascends, and trigger the SSJ transformation after say, 100 points.

我们需要一种方法来跟踪悟空在他上升时的功率水平,并在说出100分之后触发SSJ转换。

We can start his power off at 1, and increase it while the user holds a key down.

我们可以从1开始关闭电源,然后在用户按住键的同时增加电源。

RxJS运算符 (RxJS Operators)

Operators are where RxJS really shines. We can use pure functions to describe how data should transform through the stream.

操作员是RxJS真正发挥作用的地方。 我们可以使用纯函数来描述数据应如何在流中进行转换。

When the user holds a key down, let’s transform those emissions into a number that increases over time.

当用户按下某个键时,让我们将这些排放量转换为随时间增加的排放量。

扫瞄 (Scan)

The scan operator is perfect for this. It’s like Array.reduce, but it emits as it’s reducing.

扫描运算符非常适合此操作。 这就像Array.reduce ,但它发出的,因为它的减少

For example, if you have an array of numbers:

例如,如果您有一个数字数组:

nums = [1, 2, 3, 4, 5];

And wish to add them up, reduce is a great choice.

并希望将它们加起来, reduce是一个不错的选择。

nums.reduce((a, b) => a + b, 0);
// 15

What if you want to see each addition as it happens?

如果您希望每次添加时都能看到该怎么办?

Enter scan. You can run this in our app’s console.

输入scan 。 您可以在我们的应用程序控制台中运行它。

const { from } = rxjs;
const { scan } = rxjs.operators;from([1, 2, 3, 4, 5]).pipe(scan((a, b) => a + b, 0)).subscribe(console.log);// 1 (0 + 1)
// 3 (1 + 2)
// 6 (3 + 3)
// 10 (6 + 4)
// 15 (10 + 5)

See how the emissions increase over time? We can do that with Goku as he powers up!

看看排放量如何随时间增加? 我们可以通过悟空加电来做到这一点!

const { fromEvent } = rxjs;
const { scan, tap } = rxjs.operators;const begin = fromEvent(document, 'keydown');
const end = fromEvent(document, 'keyup');begin.pipe(scan((level) => level + 1, 1),tap((level) => {console.log({ level });})).subscribe(() => {sprite.classList.add('powerup');});

We start his level at 1 and increase it by 1 every time the keydown event fires.

我们将他的级别从1开始,并在每次keydown事件触发时将其级别提高1。

And the tap operator operator lets us quickly log the value without disturbing the pipeline.

轻敲运算符运算符使我们可以快速记录该值,而不会打扰管道。

My power infinitely approaches MAXIMUM!

我的力量无限接近最大值!

超级赛亚人 (Going Super Saiyan)

We’ve trained hard, it’s time to transform.

我们经过艰苦的训练,是时候转型了。

The scan operator tracks Goku’s power level. Now we need to go SSJ when it emits 100.

scan操作员跟踪悟空的功率水平。 现在我们需要在SSJ发出100信号时使用它。

I built a map of levels: transformations. You can put it right above main.

我建立了一个levels: transformations 。 您可以将其放在main上方。

const powerLevels = {100: {current: 'base',next: 'ssj'}
};const main = () => {// ...
};

It’s overkill, but should simplify adding future transformations.

这太过分了,但是应该简化添加将来的转换的过程。

When the power level reaches a number in that powerLevels map, we’ll remove its current class from sprite and add the next class.

当功率级别达到该powerLevels映射中的一个数字时,我们将从sprite删除其current类并添加next类。

This lets us smoothly go from one transformation to the next.

这使我们能够顺利地从一种转换过渡到另一种转换。

Here’s the code.

这是代码。

const { fromEvent } = rxjs;
const { filter, map, scan, tap } = rxjs.operators;const begin = fromEvent(document, 'keydown');
const end = fromEvent(document, 'keyup');begin.pipe(scan((level) => level + 1, 1),tap((level) => {console.log({ level });sprite.classList.add('powerup');}),map((level) => powerLevels[level]),filter((level) => level && level.next)).subscribe(({ current, next }) => {sprite.classList.remove(current);sprite.classList.add(next);});

地图和过滤器 (Map and Filter)

Adding the powerup class now happens inside of tap, because it should always happen. The SSJ transformation however, shouldn’t always happen.

现在添加powerup类发生在tap ,因为它应该总是发生。 但是,SSJ转换不应该总是发生。

Using map, the latest power level becomes an entry in the powerLevels map. We use filter to check if the entry exists and has a .next property.

使用map ,最新功率级别将成为powerLevels映射中的一个条目。 我们使用filter检查条目是否存在具有.next属性。

If it does, that means Goku can go even further beyond! Our .subscribe will swap current and next as class names on sprite.

如果可以,那就意味着悟空可以走得更远! 我们的.subscribe将在sprite上交换current名称和next作为类名。

The end result?

最终结果?

功率计 (Power Meter)

You’re having as much fun as I am, right? Unfortunately, our user won’t.

你和我一样开心,对吧? 不幸的是,我们的用户不会。

They can’t see how high Goku’s power level is! They won’t know how to open the DevTools console. We must remedy this!

他们看不到悟空的功率等级有多高! 他们不知道如何打开DevTools控制台。 我们必须对此进行补救!

Let’s improve our UX by filling the power meter. You can put this above main.

让我们通过填充功率计来改善用户体验。 您可以将其放在main之上。

const fillMeter = (level) => {const limit = 100;if (level >= limit) {return;}const containerWidth = meterContainer.offsetWidth;const newWidth = (level / limit) * containerWidth;meter.style.width = `${newWidth}px`;
};

And call it inside tap.

并在tap调用它。

tap((level) => {console.log({ level });sprite.classList.add('powerup');fillMeter(level);
});

And here we go:

现在我们开始:

走得更远 (Going Even Further Beyond)

Unlocking more transformations is just a matter of adding sprites, and updating our powerLevels map. If you’re interested, submit a PR on the repo and we’ll definitely talk.

解锁更多转换只是添加精灵,并更新我们的powerLevels映射。 如果您有兴趣,请在仓库中提交PR,我们一定会谈。

Here’s the original sprite sheet. Enjoy!

这是原始的精灵表 。 请享用!

翻译自: https://www.freecodecamp.org/news/go-super-saiyan-with-rxjs-observables-d4681ae51930/

rxjs 怎么使用

rxjs 怎么使用_使用RxJS Observables进行SUPER SAIYAN相关推荐

  1. 你会用RxJS吗?【初识 RxJS中的Observable和Observer】

    概念 RxJS是一个库,可以使用可观察队列来编写异步和基于事件的程序的库. RxJS 中管理和解决异步事件的几个关键点: Observable: 表示未来值或事件的可调用集合的概念. Observer ...

  2. pythonsuper函数_认识python中的super函数

    需求分析 在类继承中,存在这么一种情况: class Human(object): def Move(self): print("我会走路...") class Man(Human ...

  3. 根据父类id查询所有的父级_父类子类抽象类,super final 重写方法,搞懂继承中复杂的知识点...

    继承 继承(Inheritance)可以实现类之间共享属性和方法,是面向对象编程的另一个特性 使用继承可以最大限度地实现代码复用. 定义:继承就是在已有类的基础上构建新的类,一个类继承已有类后,可以对 ...

  4. idea实现抽象类的所有抽象方法_父类子类抽象类,super final 重写方法,搞懂继承中复杂的知识点

    继承 继承(Inheritance)可以实现类之间共享属性和方法,是面向对象编程的另一个特性 使用继承可以最大限度地实现代码复用. 定义:继承就是在已有类的基础上构建新的类,一个类继承已有类后,可以对 ...

  5. python super()方法的作用_详解python的super()的作用和原理

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...

  6. 超级vga显示卡_技嘉推出显示卡Super Overclock超频系列

    业界首创金手套GPU Sorting技术结合顶级用料,创造终极效能传说 2009年,台湾,台北- 显示卡领导厂商技嘉科技今日隆重推出超级超频版显示卡.技嘉Super Overclock系列针对顶级硬件 ...

  7. 影驰名人堂送的机器人_顺丰影驰rtx2080s super名人堂hof好不好?老司机深度剖析真心话 | 智能扫地机器人评测...

    顺丰影驰rtx2080s super名人堂hof好不好?老司机深度剖析真心话全新一代 实时光线追踪 高端游戏显卡 顺丰影驰rtx2080s super名人堂hof目前这款券后到手价格5299>& ...

  8. unity跑酷怎么添加金币_超级酱跑酷:SUPER UNITYCHAN RUN修改金币方法

    在玩<超级酱跑酷:SUPER UNITYCHAN RUN>的时候,想必很多玩家因金币不够而导致自己做不了很多事情,在这里小编给各位玩家介绍几款好用的修改器,如:八门神器.葫芦侠.烧饼修改器 ...

  9. rxjs处理http请求超时

    博客原文地址 使用场景 用户进行一个操作请求后台而长时间未响应,我们希望给用户一个信息展示(请求超时,网络不好-). RxJS实现 关于RxJS请看这里 我这个功能的实现主要使用 delay,race ...

最新文章

  1. Springboot在IDEA热部署的配置方法
  2. 304 Not Modified
  3. python多进程加快for循环_python多进程 通过for循环 join 的问题
  4. 美团的DBProxy实践
  5. extjs 方法执行顺序_TestNG之注解变压器amp;方法拦截器
  6. python静态方法和类方法的区别_python中类的静态方法和类的类方法
  7. oracle rac升级补丁及中间的错误提示
  8. 找不到aspnet用户权限的解决方法
  9. 32线性空间06——行空间和左零空间
  10. 进阶运维:SSH无缝切换远程加密
  11. kubernetes之初始容器(init container)
  12. 污水流量计常见的三种电磁损耗的简单介绍
  13. win10内存占用率过高怎么办_内存占用率过高怎么办?Win10电脑内存占用率很高原因和解决方法...
  14. Debian10英语环境安装搜狗输入法
  15. matlab线性回归程序,MATLAB 线性回归
  16. 搭建私有云cloudreve教程
  17. 《动手学深度学习》task3_3 循环神经网络进阶
  18. putty乱码解决方案
  19. vue 实现手写电子签名/生成图片
  20. Postman内置的动态变量

热门文章

  1. 【性能优化实战】java验证码识别训练
  2. java中的几种泛型类——HashSet、HashMap、TreeSet、TreeMap,遍历map,排序,HashTable比较
  3. 使用thinkPHP做注册程序的实例
  4. 20155320《网络对抗》Exp4 恶意代码分析
  5. C# 控件双缓冲控制 ControlStyles 枚举详解
  6. HDU 1950 Bridging signals
  7. 客户每次请求Web页面过程
  8. Spring Aop之Advisor解析
  9. 计算机视觉-自定义对象检测器
  10. Teradata QueryGrid整合最佳分析技术 拓展客户选择空间