本文翻译自:Angular/RxJs When should I unsubscribe from `Subscription`

When should I store the Subscription instances and invoke unsubscribe() during the NgOnDestroy life cycle and when can I simply ignore them? 在NgOnDestroy生命周期中,什么时候应该存储Subscription实例并调用unsubscribe() ?什么时候可以忽略它们?

Saving all subscriptions introduces a lot of mess into component code. 保存所有订阅会在组件代码中带来很多麻烦。

HTTP Client Guide ignore subscriptions like this: HTTP客户端指南会忽略这样的订阅:

getHeroes() {this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes,error =>  this.errorMessage = <any>error);
}

In the same time Route & Navigation Guide says that: 同时,《 路线与导航指南 》指出:

Eventually, we'll navigate somewhere else. 最终,我们将导航到其他地方。 The router will remove this component from the DOM and destroy it. 路由器将从DOM中删除此组件并销毁它。 We need to clean up after ourselves before that happens. 我们需要在此之前进行自我清理。 Specifically, we must unsubscribe before Angular destroys the component. 具体来说,我们必须在Angular销毁组件之前取消订阅。 Failure to do so could create a memory leak. 否则可能会导致内存泄漏。

We unsubscribe from our Observable in the ngOnDestroy method. 我们通过ngOnDestroy方法取消订阅Observable

private sub: any;ngOnInit() {this.sub = this.route.params.subscribe(params => {let id = +params['id']; // (+) converts string 'id' to a numberthis.service.getHero(id).then(hero => this.hero = hero);});
}ngOnDestroy() {this.sub.unsubscribe();
}

#1楼

参考:https://stackoom.com/question/2ZThe/Angular-RxJs我应该何时退订-Subscription


#2楼

Angular 2 official documentation provides an explanation for when to unsubscribe and when it can be safely ignored. Angular 2官方文档提供了有关何时退订以及何时可以安全忽略的说明。 Have a look at this link: 看一下这个链接:

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

Look for the paragraph with the heading Parent and children communicate via a service and then the blue box: 查找标题为“ 父母和子女通过服务进行交流”的段落,然后显示蓝色框:

Notice that we capture the subscription and unsubscribe when the AstronautComponent is destroyed. 请注意,当AstronautComponent被销毁时,我们捕获了订阅并取消订阅。 This is a memory-leak guard step. 这是内存泄漏保护措施。 There is no actual risk in this app because the lifetime of a AstronautComponent is the same as the lifetime of the app itself. 此应用程序没有实际风险,因为AstronautComponent的寿命与应用程序本身的寿命相同。 That would not always be true in a more complex application. 在更复杂的应用程序中,并非总是如此。

We do not add this guard to the MissionControlComponent because, as the parent, it controls the lifetime of the MissionService. 我们不将此防护添加到MissionControlComponent中,因为它作为父级控制着MissionService的生命周期。

I hope this helps you. 我希望这可以帮助你。


#3楼

It depends. 这取决于。 If by calling someObservable.subscribe() , you start holding up some resource that must be manually freed-up when the lifecycle of your component is over, then you should call theSubscription.unsubscribe() to prevent memory leak. 如果通过调用someObservable.subscribe()开始保存一些资源,这些资源在组件的生命周期结束时必须手动释放,则应调用theSubscription.unsubscribe()以防止内存泄漏。

Let's take a closer look at your examples: 让我们仔细看看您的示例:

getHero() returns the result of http.get() . getHero()返回的结果http.get() If you look into the angular 2 source code , http.get() creates two event listeners: 如果查看angular 2 源代码 ,则http.get()创建两个事件侦听器:

_xhr.addEventListener('load', onLoad);
_xhr.addEventListener('error', onError);

and by calling unsubscribe() , you can cancel the request as well as the listeners: 通过调用unsubscribe() ,您可以取消请求以及侦听器:

_xhr.removeEventListener('load', onLoad);
_xhr.removeEventListener('error', onError);
_xhr.abort();

Note that _xhr is platform specific but I think it's safe to assume that it is an XMLHttpRequest() in your case. 请注意, _xhr是特定_xhr平台的,但是我认为可以安全地假定它是XMLHttpRequest()

Normally, this is enough evidence to warrant a manual unsubscribe() call. 通常,这足以保证手动进行unsubscribe()调用。 But according this WHATWG spec , the XMLHttpRequest() is subject to garbage collection once it is "done", even if there are event listeners attached to it. 但是根据此WHATWG规范 , XMLHttpRequest()一旦“完成”,就将进行垃圾回收,即使已附加事件侦听器也是如此。 So I guess that's why angular 2 official guide omits unsubscribe() and lets GC clean up the listeners. 所以我想这就是为什么angular 2官方指南省略了unsubscribe()并让GC清理监听器的原因。

As for your second example, it depends on the implementation of params . 至于第二个示例,它取决于params的实现。 As of today, the angular official guide no longer shows unsubscribing from params . 从今天起,有角度的官方指南不再显示对params取消订阅。 I looked into src again and found that params is a just a BehaviorSubject . 我再次查看了src ,发现params只是一个BehaviorSubject 。 Since no event listeners or timers were used, and no global variables were created, it should be safe to omit unsubscribe() . 由于没有使用事件侦听器或计时器,也没有创建全局变量,因此省略unsubscribe()应该是安全的。

The bottom line to your question is that always call unsubscribe() as a guard against memory leak, unless you are certain that the execution of the observable doesn't create global variables, add event listeners, set timers, or do anything else that results in memory leaks. 您问题的底线是,始终调用unsubscribe()来防止内存泄漏,除非您确定observable的执行不会创建全局变量,添加事件侦听器,设置计时器或执行任何其他导致结果的操作在内存泄漏。

When in doubt, look into the implementation of that observable. 如有疑问,请查看该可观察的实现。 If the observable has written some clean up logic into its unsubscribe() , which is usually the function that is returned by the constructor, then you have good reason to seriously consider calling unsubscribe() . 如果可观察对象已在其unsubscribe()编写了一些清理逻辑,通常是构造函数返回的函数,则您有充分的理由认真考虑调用unsubscribe()


#4楼

--- Edit 4 - Additional Resources (2018/09/01) -编辑4-其他资源(2018/09/01)

In a recent episode of Adventures in Angular Ben Lesh and Ward Bell discuss the issues around how/when to unsubscribe in a component. 在最近的《 Angular冒险》中, Ben Lesh和Ward Bell讨论了如何/何时取消订阅组件中的问题。 The discussion starts at about 1:05:30. 讨论从大约1:05:30开始。

Ward mentions right now there's an awful takeUntil dance that takes a lot of machinery and Shai Reznik mentions Angular handles some of the subscriptions like http and routing . 沃德(Ward) right now there's an awful takeUntil dance that takes a lot of machinery提到right now there's an awful takeUntil dance that takes a lot of machinery而Shai Reznik则提到Angular handles some of the subscriptions like http and routing

In response Ben mentions that there are discussions right now to allow Observables to hook into the Angular component lifecycle events and Ward suggests an Observable of lifecycle events that a component could subscribe to as a way of knowing when to complete Observables maintained as component internal state. 作为回应,Ben提到,现在正在进行讨论,以允许Obse​​rvables参与Angular组件的生命周期事件,Ward建议组件可以订阅的Observable生命周期事件,以了解何时完成以组件内部状态维护的Observables。

That said, we mostly need solutions now so here are some other resources. 就是说,我们现在最需要解决方案,因此这里有一些其他资源。

  1. A recommendation for the takeUntil() pattern from RxJs core team member Nicholas Jamieson and a tslint rule to help enforce it. 来自RxJs核心团队成员Nicholas Jamieson的takeUntil()模式的建议,以及一条有助于实施的tslint规则。 https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef

  2. Lightweight npm package that exposes an Observable operator that takes a component instance ( this ) as a parameter and automatically unsubscribes during ngOnDestroy . 轻量级npm软件包,它公开一个Observable运算符,该运算符将组件实例( this )作为参数,并在ngOnDestroy期间自动取消订阅。 https://github.com/NetanelBasal/ngx-take-until-destroy https://github.com/NetanelBasal/ngx-take-until-destroy

  3. Another variation of the above with slightly better ergonomics if you are not doing AOT builds (but we should all be doing AOT now). 如果您不进行AOT构建,则上述方法的另一个变化是人体工程学要好一些(但我们现在都应该进行AOT)。 https://github.com/smnbbrv/ngx-rx-collector https://github.com/smnbbrv/ngx-rx-collector

  4. Custom directive *ngSubscribe that works like async pipe but creates an embedded view in your template so you can refer to the 'unwrapped' value throughout your template. 自定义指令*ngSubscribe工作方式类似于异步管道,但在模板中创建了嵌入式视图,因此您可以在整个模板中引用“ unwrapped”值。 https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f

I mention in a comment to Nicholas' blog that over-use of takeUntil() could be a sign that your component is trying to do too much and that separating your existing components into Feature and Presentational components should be considered. 我在Nicholas博客的评论中提到,过度使用takeUntil()可能表明您的组件正在尝试做太多事情,应该考虑将现有组件分为FeaturePresentational组件。 You can then | async 然后,您可以| async | async the Observable from the Feature component into an Input of the Presentational component, which means no subscriptions are necessary anywhere. 将Observable从Feature组件| async到Presentational组件的Input中,这意味着在任何地方都不需要订阅。 Read more about this approach here 在此处阅读有关此方法的更多信息

--- Edit 3 - The 'Official' Solution (2017/04/09) -编辑3-``官方''解决方案(2017/04/09)

I spoke with Ward Bell about this question at NGConf (I even showed him this answer which he said was correct) but he told me the docs team for Angular had a solution to this question that is unpublished (though they are working on getting it approved). 我在NGConf上与Ward Bell讨论了这个问题(我什至向他展示了这个答案,他说的是正确的),但他告诉我Angular的文档小组对这个问题尚未解决(尽管他们正在努力使它得到批准) )。 He also told me I could update my SO answer with the forthcoming official recommendation. 他还告诉我,我可以通过即将提出的官方建议来更新我的SO答案。

The solution we should all use going forward is to add a private ngUnsubscribe = new Subject(); 今后我们应该使用的解决方案是添加一个private ngUnsubscribe = new Subject(); field to all components that have .subscribe() calls to Observable s within their class code. 所有在其类代码中具有.subscribe()调用Observable的组件的字段。

We then call this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); 然后,我们将其称为this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); in our ngOnDestroy() methods. 在我们的ngOnDestroy()方法中。

The secret sauce (as noted already by @metamaker ) is to call takeUntil(this.ngUnsubscribe) before each of our .subscribe() calls which will guarantee all subscriptions will be cleaned up when the component is destroyed. 秘密之处(如@metamaker所述 )是在我们每个.subscribe()调用之前调用takeUntil(this.ngUnsubscribe) ,这将确保在销毁组件时清除所有订阅。

Example: 例:

import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';@Component({selector: 'app-books',templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {private ngUnsubscribe = new Subject();constructor(private booksService: BookService) { }ngOnInit() {this.booksService.getBooks().pipe(startWith([]),filter(books => books.length > 0),takeUntil(this.ngUnsubscribe)).subscribe(books => console.log(books));this.booksService.getArchivedBooks().pipe(takeUntil(this.ngUnsubscribe)).subscribe(archivedBooks => console.log(archivedBooks));}ngOnDestroy() {this.ngUnsubscribe.next();this.ngUnsubscribe.complete();}
}

Note: It's important to add the takeUntil operator as the last one to prevent leaks with intermediate observables in the operator chain. 注意:重要的是,将takeUntil运算符添加为最后一个,以防止运算符链中的中间可观察对象泄漏。

--- Edit 2 (2016/12/28) -编辑2(2016/12/28)

Source 5 来源5

The Angular tutorial, the Routing chapter now states the following: "The Router manages the observables it provides and localizes the subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against memory leaks, so we don't need to unsubscribe from the route params Observable." Angular教程的“路由”一章现在指出以下内容:“路由器管理它提供的可观察对象并本地化订阅。在销毁组件时清理订阅,以防止内存泄漏,因此我们无需取消订阅路线参数可观察到。” - Mark Rajcok -Mark Rajcok

Here's a discussion on the Github issues for the Angular docs regarding Router Observables where Ward Bell mentions that clarification for all of this is in the works. 这是针对有关Router Observables的Angular文档的Github问题的讨论 ,Ward Bell提到正在为所有这些问题进行澄清。

--- Edit 1 -编辑1

Source 4 来源4

In this video from NgEurope Rob Wormald also says you do not need to unsubscribe from Router Observables. 在NgEurope的这段视频中, Rob Wormald还说您不需要取消订阅Router Observables。 He also mentions the http service and ActivatedRoute.params in this video from November 2016 . 他还从2016年11月开始在此视频中提到了http服务和ActivatedRoute.params

--- Original Answer ---原始答案

TLDR: TLDR:

For this question there are (2) kinds of Observables - finite value and infinite value. 对于此问题,有(2)种Observables值- 有限值和无限值。

http Observables produce finite (1) values and something like a DOM event listener Observables produce infinite values. http Observables产生有限 (1)值,类似DOM event listener东西Observables产生无限值。

If you manually call subscribe (not using async pipe), then unsubscribe from infinite Observables . 如果您手动调用subscribe (不使用异步管道),则unsubscribe 无限的 Observables

Don't worry about finite ones, RxJs will take care of them. 不必担心有限RxJs会照顾他们。

Source 1 来源1

I tracked down an answer from Rob Wormald in Angular's Gitter here . 我在这里从Angular的Gitter中找到了 Rob Wormald的答案。

He states (i reorganized for clarity and emphasis is mine) 他指出(为清晰起见,我进行了重组,重点是我的)

if its a single-value-sequence (like an http request) the manual cleanup is unnecessary (assuming you subscribe in the controller manually) 如果它是单值序列 (例如http请求), 则不需要手动清理 (假设您手动订阅了控制器)

i should say "if its a sequence that completes " (of which single value sequences, a la http, are one) 我应该说“如果它是一个完成序列 ”(其中一个单值序列,例如la http,是一个)

if its an infinite sequence , you should unsubscribe which the async pipe does for you 如果它是无限序列则应退订异步管道为您执行的操作

Also he mentions in this youtube video on Observables that they clean up after themselves ... in the context of Observables that complete (like Promises, which always complete because they are always producing 1 value and ending - we never worried about unsubscribing from Promises to make sure they clean up xhr event listeners, right?). 他还在YouTube上有关Observables的视频中提到, they clean up after themselves ……在complete的Observables的背景下(例如Promises,由于它们始终产生1值并结束,因此它们总是完成-我们从不担心从Promises退订到确保他们清理了xhr事件监听器,对吗?)。

Source 2 来源2

Also in the Rangle guide to Angular 2 it reads 同样在Angular 2的Rangle指南中

In most cases we will not need to explicitly call the unsubscribe method unless we want to cancel early or our Observable has a longer lifespan than our subscription. 在大多数情况下,除非我们想提早取消或Observable的寿命比订阅的寿命长,否则我们无需显式调用unsubscribe方法。 The default behavior of Observable operators is to dispose of the subscription as soon as .complete() or .error() messages are published. Observable运算符的默认行为是在发布.complete()或.error()消息后立即处理订阅。 Keep in mind that RxJS was designed to be used in a "fire and forget" fashion most of the time. 请记住,RxJS被设计为大多数时候以“即弃即用”的方式使用。

When does the phrase our Observable has a longer lifespan than our subscription apply? 什么时候our Observable has a longer lifespan than our subscription短语our Observable has a longer lifespan than our subscription

It applies when a subscription is created inside a component which is destroyed before (or not 'long' before) the Observable completes. 它适用于在组件内部创建预订,而该组件在Observable完成之前被销毁(或未“长久”)的情况。

I read this as meaning if we subscribe to an http request or an observable that emits 10 values and our component is destroyed before that http request returns or the 10 values have been emitted, we are still ok! 我的意思是,如果我们订阅一个http请求或一个发出10个值的可观察对象,并且在该http请求返回或发出10个值之前销毁了我们的组件,我们还是可以的!

When the request does return or the 10th value is finally emitted the Observable will complete and all resources will be cleaned up. 当请求确实返回或最终发出第十个值时, Observable将完成,所有资源将被清理。

Source 3 来源3

If we look at this example from the same Rangle guide we can see that the Subscription to route.params does require an unsubscribe() because we don't know when those params will stop changing (emitting new values). 如果我们从相同的Rangle指南中查看此示例 ,则可以看到对route.paramsSubscription确实需要unsubscribe()因为我们不知道这些params何时会停止更改(发出新值)。

The component could be destroyed by navigating away in which case the route params will likely still be changing (they could technically change until the app ends) and the resources allocated in subscription would still be allocated because there hasn't been a completion . 通过导航可以破坏该组件,在这种情况下,路由参数可能仍会更改(它们可能会在技术上更改,直到应用结束),并且由于尚未completion因此仍将分配订阅中分配的资源。


#5楼

You don't need to have bunch of subscriptions and unsubscribe manually. 您不需要一堆订阅并手动取消订阅。 Use Subject and takeUntil combo to handle subscriptions like a boss: 使用Subject和takeUntil组合可像老板一样处理订阅:

import { Subject } from "rxjs"
import { takeUntil } from "rxjs/operators"@Component({moduleId: __moduleName,selector: "my-view",templateUrl: "../views/view-route.view.html"
})
export class ViewRouteComponent implements OnInit, OnDestroy {componentDestroyed$: Subject<boolean> = new Subject()constructor(private titleService: TitleService) {}ngOnInit() {this.titleService.emitter1$.pipe(takeUntil(this.componentDestroyed$)).subscribe((data: any) => { /* ... do something 1 */ })this.titleService.emitter2$.pipe(takeUntil(this.componentDestroyed$)).subscribe((data: any) => { /* ... do something 2 */ })//...this.titleService.emitterN$.pipe(takeUntil(this.componentDestroyed$)).subscribe((data: any) => { /* ... do something N */ })}ngOnDestroy() {this.componentDestroyed$.next(true)this.componentDestroyed$.complete()}
}

Alternative approach , which was proposed by @acumartini in comments , uses takeWhile instead of takeUntil . @acumartini在评论中提出的 替代方法使用takeWhile而不是takeUntil 。 You may prefer it, but mind that this way your Observable execution will not be cancelled on ngDestroy of your component (eg when you make time consuming calculations or wait for data from server). 您可能更喜欢它,但是请注意,这样一来,您的组件的ngDestroy上的Observable执行将不会被取消(例如,当您进行耗时的计算或等待服务器中的数据时)。 Method, which is based on takeUntil , doesn't have this drawback and leads to immediate cancellation of request. 基于takeUntil的方法没有此缺点,并导致立即取消请求。 Thanks to @AlexChe for detailed explanation in comments . 感谢@AlexChe在评论中提供详细的解释 。

So here is the code: 所以这是代码:

@Component({moduleId: __moduleName,selector: "my-view",templateUrl: "../views/view-route.view.html"
})
export class ViewRouteComponent implements OnInit, OnDestroy {alive: boolean = trueconstructor(private titleService: TitleService) {}ngOnInit() {this.titleService.emitter1$.pipe(takeWhile(() => this.alive)).subscribe((data: any) => { /* ... do something 1 */ })this.titleService.emitter2$.pipe(takeWhile(() => this.alive)).subscribe((data: any) => { /* ... do something 2 */ })// ...this.titleService.emitterN$.pipe(takeWhile(() => this.alive)).subscribe((data: any) => { /* ... do something N */ })}// Probably, this.alive = false MAY not be required here, because// if this.alive === undefined, takeWhile will stop. I// will check it as soon, as I have time.ngOnDestroy() {this.alive = false}
}

#6楼

I tried seangwright's solution (Edit 3) 我尝试了seangwright的解决方案(编辑3)

That is not working for Observable that created by timer or interval. 这不适用于计时器或时间间隔创建的Observable。

However, i got it working by using another approach: 但是,我通过使用另一种方法使其工作:

import { Component, OnDestroy, OnInit } from '@angular/core';
import 'rxjs/add/operator/takeUntil';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/Rx';import { MyThingService } from '../my-thing.service';@Component({selector: 'my-thing',templateUrl: './my-thing.component.html'
})
export class MyThingComponent implements OnDestroy, OnInit {private subscriptions: Array<Subscription> = [];constructor(private myThingService: MyThingService,) { }ngOnInit() {const newSubs = this.myThingService.getThings().subscribe(things => console.log(things));this.subscriptions.push(newSubs);}ngOnDestroy() {for (const subs of this.subscriptions) {subs.unsubscribe();}}
}

Angular / RxJs我应该何时退订`Subscription`相关推荐

  1. rxjs angular_RxJS和Angular —像专业人士一样退订

    rxjs angular All the patterns you will ever need to subscribe and unsubscribe from RxJS Observables ...

  2. 摆脱阅读黑洞,退订RSS

    "过犹不及",古人这话算是说对了.在过去的一段时间里,我订阅了大量的RSS,不过随着时间的推移,我发现我陷入了"阅读黑洞",在黑洞里我耗费了大量的业余时间,但收 ...

  3. android手机短信拦截器,垃圾短信退订套路深 手机上装拦截软件是可行方法

    原标题:垃圾短信退订套路深 手机上装拦截软件是可行方法 应对 相关数据显示,2017年通过某知名手机安全卫士拦截的骚扰电话全年共计380亿次,相比2016年的385亿次略有下降:垃圾短信方面,全年拦截 ...

  4. HarmonyOS之公共事件的发布、订阅与退订

    一.简介 ① 概念 HarmonyOS 通过 CES(Common Event Service,公共事件服务)为应用程序提供订阅.发布.退订公共事件的能力,通过 ANS(Advanced Notifi ...

  5. (Redis设计与实现-6) 频道的订阅与退订

    一.订阅频道 每当客户端执行 SUBSCRIBE 命令,订阅某个或某些频道的时候,服务器都会将客户端与被订阅的频道在 redisServer.pubsub_channels 字典中进行关联. a.如果 ...

  6. 如何使用Angular rxjs进行优雅限流

    比如我有一个按钮,我想实现在一秒之内重复点击,只算被点击一次的效果,在Angular rxjs里实现非常容易: 源代码: ngOnInit(): void {const button = docume ...

  7. 邮件退订_如何方便地退订邮件列表

    邮件退订 如果您在电子邮件讨论组中的时间足够长,则有时会看到列表成员发出的一封电子邮件,要求取消订阅. 通常,列表中的至少10个人将回复有关如何退订的说明,而另外10个人确认或评论说明将回答这10条回 ...

  8. 通过F12控制台退订育碧(Ubisoft)邮件

    之前在育碧注册了一个账号,现在每几天就给我发送邮件来推送游戏,很是不爽!! 退订步骤: 点击邮件下方的"取消订阅",跳转到新链接,但发现Unsubscribe按钮不能点击(真恶心! ...

  9. 分期花呗 账户交易通知:尾号6932客户,您的申请已通过,账户余额38139元,无手续费,点t.cn/Aijsx9vq取款,回T退订。...

    10692285499  分期花呗 账户变动通知:尾号6932客户,您的申请已通过,账户余额5000元,请及时点击t.cn/AiOMsNAm取款,回T退订. 106935276259002 分期花呗 ...

最新文章

  1. 2020 北京智源大会首日精华速递
  2. 8个概念告诉你人工智能
  3. 解决TIME_WAIT过多造成的问题
  4. HTTP,request,response
  5. mysqladmin 设置用户名初始密码报错you need the SUPER privilege for this operation
  6. 【SQL】字符型函数
  7. 提示编码有问题时,VS保存选项
  8. 全球及中国在线教育行业发展态势与营利模式咨询报告2022版
  9. 如何安装JRE8.0.202
  10. 前端电子时钟字体引入
  11. 开通一个博客,开启一个更高的要求
  12. python 进行照片分类_如何用python将文件夹中图片根据颜色分类
  13. excel表格如何转换成word表格_告诉你如何将excel表格转换成word文档
  14. 加强银行余额调节表在财务管理中的作用
  15. 竞品分析—抖音PK快手
  16. 竞技体育数据可视化与可视化分析综述
  17. 【Arch】Android系统简介
  18. 创建自定义类型转换器
  19. 哈趣K1和哈趣H1哪个性价比更高?谁更值得入手?
  20. 爬取某猫即将上映电影数据,写入excel保存

热门文章

  1. BG-UI,一个可以快速上手的后台UI框架
  2. mysql 5.1.x 比较 5.6.x版本的日志
  3. PHP操作MongoDB
  4. SpringCloud的Ribbon自定义负载均衡算法
  5. Tomcat启动过程(一):从BootStrap到EndPonit
  6. 求平均值 Avg.java
  7. ORACLE常用函数汇总【转】
  8. Adobe发布基于HTML5技术的网络开发工具以解决跨平台问题
  9. 服务器更换主板后系统无法启动
  10. CentOS下FastDFS+Nginx(单点部署)事例