百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

GetX框架里容易被忽略的那些小知识

myzbx 2025-09-24 00:42 33 浏览

在使用 GetxController(以及它的子类,如 GetxService)时,我们通常会接触到几个常见的生命周期方法,比如 onInit、onReady、onClose 等。实际上,GetX 在 Controller 的生命周期管理上提供了更细致的钩子函数,帮助我们更好地安排业务逻辑。

一、GetxController 主要生命周期方法

  • onInit()
  • onReady()
  • onClose()

这三大方法在 GetxController 中最常用,也是官方文档重点介绍的。除此之外,在 GetX 源码中还可以找到一些其他(比较少见)的生命周期方法,例如 onStart, onDelete, 以及对于 GetxService 的一些附加逻辑。

不过在常规的业务开发场景下,主要关注 onInit(), onReady() 和 onClose() 就足以应对绝大部分需求。

让我们依次了解它们在何时被调用、适合处理哪些逻辑,以及一些最佳实践。

1. onInit()

何时被调用?

  • 当 Controller 实例被 Get.put 或 Get.find(第一次获取)时,会立即调用该 Controller 的 onInit() 方法。
  • 这意味着 onInit() 通常是这个 Controller 生命周期的开端,一般在 Widget 构建之前就会执行(或者说,在页面渲染之前)。

适合处理的逻辑

  1. 变量初始化:初始化业务变量、Rx 变量等。
  2. 监听绑定:通过 ever, debounce, interval 等 Worker,在此处集中设置对 Rx 变量的监听。
  3. 依赖注入:如果这个控制器需要依赖某些服务(也可以用 Bindings),也可以在这里尝试使用 Get.find 获取并赋值。
  4. 轻量级网络请求:如果数据的优先级比较高,需要在页面显示之前就拿到(如基础配置、用户信息),可以在 onInit()里发请求。但如果请求会阻塞页面渲染过久,可以考虑放到 onReady()。
class HomeController extends GetxController {
var counter = 0.obs;
@override
void onInit() {
super.onInit();
print('onInit -> Controller开始初始化');
// 设置 Worker,比如监听 counter 的变化
ever(counter, (value) {
print('counter changed: $value');
});
// 如果需要请求一些不太大的数据,比如配置文件
fetchInitialData();
}
void fetchInitialData() {
// ...
}
}

注意:如果请求会比较耗时,且必须在页面完全渲染后才做,不建议放在 onInit(),否则用户可能在空白页面等待,体验不好。这时应该考虑放到 onReady()。

2. onReady()

何时被调用?

  • 当 Widget(绑定了该 Controller 的页面)渲染完成后,就会调用 onReady()。
  • 它比 onInit() 更晚,通常意味着页面已经可见,此时做一些需要依赖“页面可见”的操作会更合适。

适合处理的逻辑

  1. 网络请求 / 动画启动:页面渲染完成后,再开始长耗时操作或加载数据,可以先让用户看到页面框架,避免一直等待空白屏。
  2. 弹窗 / SnackBar:有时需要在页面刚显示时弹出引导或提示,也可以在这里调用。
  3. 启动轮询 / 计时器:页面已经加载完,可能需要周期性地更新数据。
class ProfileController extends GetxController {
var profile = Rxn<UserProfile>(); // 可能是null
@override
void onInit() {
super.onInit();
// 这里可以做一些很轻量的初始化
// 例如:profile.value = localCache?.readProfile();
}
@override
void onReady() {
super.onReady();
print('onReady -> 页面已经渲染完成');
// 进行相对耗时或需要页面已加载才执行的网络请求
fetchUserProfile();
}
void fetchUserProfile() async {
// ... 异步请求
// profile.value = ...
}
}

PS:有些人也喜欢把所有网络请求都放 onInit(),这样页面一进来就开始请求。并不是不可以,但若数据体量较大,则可能延迟页面的渲染,用户体验没有 onReady() 友好。

3. onClose()

何时被调用?

  • 当 Controller 所在的页面被销毁、或者我们主动调用了 Get.delete()(若此 Controller 未被其它依赖持有)时,会触发 onClose().
  • 在默认的 SmartManagement.full 模式下,离开页面并且路由不再保留时,就会自动销毁该 Controller 并调用 onClose()。

适合处理的逻辑

  1. 释放资源:例如取消订阅、关闭流、dispose Timer / Worker、断开 WebSocket 等。
  2. 保存数据:在页面关闭时,将一些状态持久化到本地或共享存储。
  3. 取消请求:如果有网络请求或异步操作在进行,可以在这里清理或取消。
class ChatController extends GetxController {
late final StreamSubscription messageSub;
@override
void onInit() {
super.onInit();
messageSub = ChatService.onNewMessage.listen((msg) {
// handle new message
});
}
@override
void onClose() {
// 页面销毁时,取消监听,避免内存泄漏
messageSub.cancel();
super.onClose();
}
}

注意:若你在 onInit() 或其他地方启动了定时器 (Timer)、stream 监听、socket 连接等,一定要在 onClose() 中主动释放,否则会出现内存泄漏或意外的后台执行。

二、其他较少见的生命周期/方法

onStart()

在部分早期版本或某些扩展中,可能会看到 onStart(),但在官方的最新控制器中并没有默认实现。onStart() 更类似于一个“刚开始启动 Controller”的时刻,一般你可以把它当作是比 onInit() 更早的一层(但通常我们不使用它)。

目前常见的场景会使用 onInit() 即可满足需求。若你要在生成 Controller 之后,还没正式初始化前执行某些事情,可以考虑直接在构造函数或 onInit() 里处理。

onDelete()

当使用 Get.delete(force: true) 时,可能会触发到 onDelete。它在 GetX 的内部封装里用来清理一些辅助资源。大多数时候你只需要在 onClose() 中进行资源释放即可。

三、在不同生命周期做什么业务最合适

下面做一个小结,可以作为一个通用的“对照表”:

生命周期方法

何时调用 & 适用场景

建议做的事

不建议做的事

onInit()

1. 当 Controller 被注入(或 Get.find 首次被调用)时触发
2. 页面构建前执行,属于 Controller 的初始化阶段

1. 绑定 Worker(ever, debounce, interval 等)
2. 依赖注入或 Get.find()
3. 轻量级数据准备(如同步读取、少量网络请求)
4. 做一些初步逻辑(设置默认值、读取缓存等)

1. 不要进行非常耗时的操作(会阻塞页面首帧渲染)
2. 不要在此处弹出对话框或执行大量 UI 操作(此时页面尚未渲染)

onReady()

1. 当页面(Widget)已完成渲染后触发
2. 比 onInit() 更晚,可确保用户已能看到页面主体

1. 加载大数据或较长耗时异步请求(确保页面不白屏)
2. 启动动画、弹出对话框或引导
3. 获取用户真正所需的核心数据(如详情、列表)
4. 启动定时器、轮询等(页面已可见,用户体验更好)

1. 不适合过早执行的操作(应放在 onInit() 中)
2. 如果某操作必须在页面显示前完成,放在 onInit() 但要注意影响首屏渲染,需平衡用户体验

onClose()

1. 当 Controller 被销毁或页面结束路由栈时触发
2. 在默认 SmartManagement.full 模式下,离开页面会销毁对应 Controller

1. 释放资源(如 Stream、Timer、WebSocket、Controller)
2. 保存页面状态或数据(写入本地或全局服务)
3. 取消未完成的网络请求(避免后台无用操作)

1. 避免过多耗时操作(用户已离开页面)
2. 不建议执行过于复杂的逻辑,可考虑改为后台异步执行或交给全局服务处理

四、完整实例

以下示例演示一个带有 Worker、网络请求、资源释放的 Controller,并在不同生命周期执行不同逻辑。

class ProductController extends GetxController {
// 产品列表
final products = <Product>[].obs;
// 搜索关键字
final searchQuery = ''.obs;
// 定时轮询的 timer
Timer? pollingTimer;
@override
void onInit() {
super.onInit();
print('ProductController -> onInit');
// 1. Worker - 监听搜索关键字变化,触发搜索
debounce(searchQuery, (_) {
fetchProducts(searchQuery.value);
}, time: Duration(milliseconds: 500));
// 2. 可以进行一些轻量级初始化操作,或者尝试用局部缓存
final cachedData = LocalCache.get('product_list');
if (cachedData != null) {
products.assignAll(cachedData);
}
}
@override
void onReady() {
super.onReady();
print('ProductController -> onReady');
// 页面已渲染,可以进行真正的网络请求
fetchProducts();
// 每 30 秒轮询一次数据
pollingTimer = Timer.periodic(Duration(seconds: 30), (timer) {
fetchProducts();
});
}
@override
void onClose() {
print('ProductController -> onClose');
// 1. 释放 Timer
pollingTimer?.cancel();
// 2. 可能需要保存最后的产品列表
LocalCache.save('product_list', products.toList());
// 3. 执行父类 onClose
super.onClose();
}
void fetchProducts([String? query]) async {
// ... 调接口获取产品列表
// products.value = ...
print('Fetching products with query: $query');
}
}
  • 在 onInit() 中,设置了 searchQuery 的去抖监听,并尝试加载本地缓存数据。
  • 在 onReady() 中,页面渲染完成后进行网络请求、启动定时轮询。
  • 在 onClose() 中,销毁 Timer 并保存数据到本地。

五、总结

onInit():

  • 适合做初始绑定、轻量初始化、Worker 监听
  • 时间点:Controller 被创建、注入后立即执行

onReady():

  • 适合在页面渲染后再做更多数据加载、动画启动、提示弹窗
  • 时间点:Widget build 完成后

onClose():

  • 适合资源释放、销毁定时器或保存数据
  • 时间点:页面或 Controller 被销毁前

合理利用 GetX Controller 的这些生命周期方法,可以让你的业务逻辑分层更加清晰、页面渲染和数据请求的时机更可控,也更便于管理资源和避免内存泄漏。

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 &quot;小贱贱&quot;韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...