当前位置:  首页>> 技术小册>> 微信小程序全栈开发实战(上)

55 | 网络接口简介(六):关于Page页面隐藏代码执行及Promise对象的catch处理的补充

在微信小程序的全栈开发过程中,网络接口的使用是不可或缺的一环,它连接着前端页面与后端服务,实现了数据的动态交互。然而,在实际开发中,我们不仅要关注网络请求的发送与接收,还需要考虑页面生命周期对网络请求的影响,特别是当页面隐藏时如何处理未完成的网络请求,以及如何通过Promise的catch方法优雅地处理网络请求中可能出现的异常。本章将深入探讨这两个重要话题。

一、Page页面隐藏时的代码执行

微信小程序中,页面的生命周期管理对于开发者来说至关重要。理解并掌握页面从创建到销毁的各个阶段,能够帮助我们更好地控制资源的加载与释放,优化用户体验。当页面因为用户的操作(如滑动到其他页面、点击tab切换等)而隐藏时,如果此时有未完成的网络请求,就需要我们特别处理这些请求,避免造成资源浪费或数据不一致的问题。

1.1 页面生命周期方法

微信小程序提供了丰富的页面生命周期方法,其中与页面隐藏相关的主要有onHideonUnload

  • onHide:页面隐藏时触发。一个页面只会调用一次onUnload,而onHide可能会被调用多次,如多次返回到该页面,onHide都会被执行。
  • onUnload:页面卸载时触发,表示该页面的实例将被销毁,所有的数据、事件监听器以及定时器都将被清理。
1.2 隐藏时网络请求的处理

当页面隐藏时,如果仍有网络请求在进行,可以采取以下几种策略来处理:

  • 取消请求:对于可以取消的请求(如使用wx.request时,若后端支持,可通过设置请求头或发送特定请求来中断),可以在onHide方法中取消这些请求,避免资源浪费。
  • 忽略结果:如果不希望因为页面隐藏就取消请求,但又不希望处理返回的结果(比如更新UI),可以在onHide中设置一个标志位,在请求回调中根据这个标志位决定是否处理结果。
  • 延迟处理:对于某些需要较长时间处理的请求,即使页面隐藏,也可能需要继续等待结果(如上传文件、提交表单等)。这时可以在全局变量中记录请求状态,并在页面重新显示时检查并处理这些状态。
1.3 示例代码

假设有一个需要较长时间处理的数据提交请求,我们可以在页面隐藏时设置一个标志位,以决定是否处理返回的数据。

  1. Page({
  2. data: {
  3. isPageActive: true, // 标志页面是否活跃
  4. },
  5. onLoad: function() {
  6. // 发起网络请求
  7. this.sendRequest();
  8. },
  9. onHide: function() {
  10. this.setData({
  11. isPageActive: false, // 页面隐藏,设置标志位
  12. });
  13. },
  14. sendRequest: function() {
  15. wx.request({
  16. url: 'https://example.com/api/data',
  17. method: 'POST',
  18. data: {
  19. // 请求数据
  20. },
  21. success: (res) => {
  22. if (this.data.isPageActive) {
  23. // 页面活跃时处理结果
  24. console.log('处理结果', res.data);
  25. } else {
  26. // 页面不活跃时,可选择记录日志、忽略结果等
  27. console.log('页面已隐藏,忽略请求结果');
  28. }
  29. },
  30. fail: (err) => {
  31. // 错误处理
  32. console.error('请求失败', err);
  33. }
  34. });
  35. },
  36. // 其他方法...
  37. });

二、Promise对象的catch处理的补充

在JavaScript中,Promise是处理异步操作的重要工具,它提供了一种更加简洁和强大的方式来处理异步逻辑。在微信小程序中,网络请求等异步操作也常常通过Promise来封装。正确使用Promise的thencatch方法,能够让我们更好地控制异步流程,并优雅地处理可能出现的异常。

2.1 Promise基础

Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise对象代表了一个最终可能完成或失败的操作及其结果值。

  • then方法接收两个可选的回调函数作为参数:第一个在Promise成功时被调用,第二个在Promise失败时被调用(但通常不推荐在then中处理错误,而是使用catch)。
  • catch方法用于指定Promise对象失败时的回调函数。
2.2 catch处理的最佳实践
  • 始终使用catch:无论你的Promise链中有多少个then,都应该在链的末尾添加一个catch来捕获可能发生的任何错误。这可以确保所有潜在的错误都能被捕获并处理。
  • 避免在then中嵌套catch:虽然技术上可行,但在then中嵌套catch会使代码结构变得复杂且难以维护。应尽可能在链的末尾统一处理错误。
  • 错误传播:如果then中的回调函数没有处理错误(即没有返回另一个Promise或抛出错误),那么这个错误会“冒泡”到链中的下一个catch。利用这一特性,可以集中处理多个then中的错误。
  • 错误日志:在catch中记录详细的错误日志是非常重要的,这有助于后续的问题排查和修复。
2.3 示例代码

以下是一个使用Promise进行网络请求,并在catch中处理错误的示例。

  1. function fetchData() {
  2. return new Promise((resolve, reject) => {
  3. wx.request({
  4. url: 'https://example.com/api/data',
  5. success: (res) => {
  6. if (res.statusCode === 200) {
  7. resolve(res.data);
  8. } else {
  9. reject(new Error('请求失败,状态码非200'));
  10. }
  11. },
  12. fail: (err) => {
  13. reject(err);
  14. }
  15. });
  16. });
  17. }
  18. fetchData()
  19. .then(data => {
  20. console.log('数据获取成功', data);
  21. // 假设这里还有其他异步操作...
  22. return anotherAsyncOperation(data); // 假设这也是一个返回Promise的函数
  23. })
  24. .then(result => {
  25. console.log('另一个异步操作成功', result);
  26. })
  27. .catch(error => {
  28. console.error('请求过程中发生错误', error);
  29. // 这里可以添加更多的错误处理逻辑,如用户提示、错误上报等
  30. });

在以上示例中,我们定义了一个fetchData函数,它返回一个Promise对象,用于封装网络请求的逻辑。然后,我们通过链式调用thencatch来处理异步请求的成功结果和可能发生的错误。这样的代码结构清晰,易于理解和维护。

综上所述,对于微信小程序中Page页面隐藏时的代码执行及Promise对象的catch处理,我们需要关注页面生命周期对网络请求的影响,合理控制资源的使用,并通过优雅的错误处理机制来提升应用的健壮性和用户体验。


该分类下的相关小册推荐: