B2B网络软件

标题: AIWROK软件定时检查页面状态防止卡死技巧 [打印本页]

作者: YYPOST群发软件    时间: 2 小时前
标题: AIWROK软件定时检查页面状态防止卡死技巧
AIWROK软件定时检查页面状态防止卡死技巧


AIWROK软件定时检查页面状态防止卡死技巧 B2B网络软件

  1. /**
  2. * AIWROK 脚本任务管理器 - 实用工具集
  3. *
  4. * 针对安卓自动化脚本开发的实际需求:
  5. * 1. 定时检查页面状态(防止卡死)
  6. * 2. 超时保护机制(避免无限等待)
  7. * 3. 任务重试机制(提高稳定性)
  8. * 4. 执行进度监控(方便调试)
  9. *
  10. * 这些都是写脚本时经常遇到的痛点!
  11. */

  12. // ==================== 核心工具类 ====================

  13. /**
  14. * 超时控制器
  15. * 解决:等待某个条件时,防止无限等待导致脚本卡死
  16. */
  17. function TimeoutController() {
  18.     var timeoutId = null;
  19.     var isCompleted = false;
  20.    
  21.     /**
  22.      * 启动超时保护
  23.      * @param {Number} timeoutMs - 超时时间(毫秒)
  24.      * @param {Function} onTimeout - 超时回调
  25.      * @returns {Object} 控制器对象
  26.      */
  27.     this.start = function(timeoutMs, onTimeout) {
  28.         if (timeoutId !== null) {
  29.             this.cancel();
  30.         }
  31.         
  32.         isCompleted = false;
  33.         var self = this;
  34.         
  35.         timeoutId = runTime.setTimeout(function() {
  36.             if (!isCompleted) {
  37.                 print.log("[超时控制] ⚠ 操作超时!");
  38.                 if (onTimeout) {
  39.                     onTimeout();
  40.                 }
  41.             }
  42.         }, timeoutMs);
  43.         
  44.         print.log("[超时控制] ✓ 已启动超时保护 (" + timeoutMs + "ms)");
  45.         return this;
  46.     };
  47.    
  48.     /**
  49.      * 标记完成(清除超时)
  50.      */
  51.     this.complete = function() {
  52.         if (!isCompleted && timeoutId !== null) {
  53.             runTime.stopTimeout(timeoutId);
  54.             timeoutId = null;
  55.             isCompleted = true;
  56.             print.log("[超时控制] ✓ 操作完成,已取消超时保护");
  57.         }
  58.         return this;
  59.     };
  60.    
  61.     /**
  62.      * 取消超时保护
  63.      */
  64.     this.cancel = function() {
  65.         if (timeoutId !== null) {
  66.             runTime.stopTimeout(timeoutId);
  67.             timeoutId = null;
  68.             print.log("[超时控制] ✓ 已取消超时保护");
  69.         }
  70.         return this;
  71.     };
  72. }

  73. /**
  74. * 重试控制器
  75. * 解决:网络请求、节点查找等可能失败的操作,自动重试
  76. */
  77. function RetryController() {
  78.     var maxRetries = 3;
  79.     var currentRetry = 0;
  80.     var retryDelay = 2000; // 重试间隔(毫秒)
  81.    
  82.     /**
  83.      * 配置重试参数
  84.      * @param {Number} maxRetries - 最大重试次数
  85.      * @param {Number} delay - 重试间隔(毫秒)
  86.      */
  87.     this.configure = function(maxRetries, delay) {
  88.         this.maxRetries = maxRetries;
  89.         this.retryDelay = delay || 2000;
  90.         return this;
  91.     };
  92.    
  93.     /**
  94.      * 执行带重试的操作
  95.      * @param {Function} operation - 要执行的操作(返回true表示成功)
  96.      * @param {String} operationName - 操作名称(用于日志)
  97.      * @param {Function} onSuccess - 成功回调
  98.      * @param {Function} onFail - 失败回调
  99.      */
  100.     this.execute = function(operation, operationName, onSuccess, onFail) {
  101.         currentRetry = 0;
  102.         var self = this;
  103.         
  104.         function tryExecute() {
  105.             currentRetry++;
  106.             print.log("[重试控制] 尝试 " + operationName + " (第" + currentRetry + "/" + self.maxRetries + "次)");
  107.             
  108.             var success = operation();
  109.             
  110.             if (success) {
  111.                 print.log("[重试控制] ✓ " + operationName + " 成功!");
  112.                 if (onSuccess) {
  113.                     onSuccess();
  114.                 }
  115.             } else {
  116.                 if (currentRetry < self.maxRetries) {
  117.                     print.log("[重试控制] ⚠ " + operationName + " 失败," +
  118.                              (self.retryDelay/1000) + "秒后重试...");
  119.                     
  120.                     runTime.setTimeout(function() {
  121.                         tryExecute();
  122.                     }, self.retryDelay);
  123.                 } else {
  124.                     print.log("[重试控制] ✗ " + operationName + " 失败,已达最大重试次数");
  125.                     if (onFail) {
  126.                         onFail();
  127.                     }
  128.                 }
  129.             }
  130.         }
  131.         
  132.         tryExecute();
  133.     };
  134. }

  135. /**
  136. * 心跳检测器
  137. * 解决:长时间运行的脚本,定期检查是否还在正常工作
  138. */
  139. function HeartbeatMonitor() {
  140.     var intervalId = null;
  141.     var heartbeatCount = 0;
  142.     var lastHeartbeatTime = null;
  143.     var checkInterval = 5000; // 心跳间隔(毫秒)
  144.    
  145.     /**
  146.      * 启动心跳监控
  147.      * @param {Number} interval - 心跳间隔(毫秒)
  148.      * @param {Function} onHeartbeat - 每次心跳的回调
  149.      */
  150.     this.start = function(interval, onHeartbeat) {
  151.         if (interval) {
  152.             checkInterval = interval;
  153.         }
  154.         
  155.         heartbeatCount = 0;
  156.         var self = this;
  157.         
  158.         intervalId = runTime.setInterval(function() {
  159.             heartbeatCount++;
  160.             lastHeartbeatTime = new Date();
  161.             
  162.             print.log("[心跳监控] ♥ 心跳 #" + heartbeatCount + " - " +
  163.                      lastHeartbeatTime.toLocaleTimeString());
  164.             
  165.             if (onHeartbeat) {
  166.                 onHeartbeat(heartbeatCount);
  167.             }
  168.         }, checkInterval);
  169.         
  170.         print.log("[心跳监控] ✓ 心跳监控已启动 (间隔:" + checkInterval + "ms)");
  171.         return this;
  172.     };
  173.    
  174.     /**
  175.      * 停止心跳监控
  176.      */
  177.     this.stop = function() {
  178.         if (intervalId !== null) {
  179.             runTime.clearInterval(intervalId);
  180.             intervalId = null;
  181.             print.log("[心跳监控] ✓ 心跳监控已停止 (共" + heartbeatCount + "次)");
  182.         }
  183.         return this;
  184.     };
  185.    
  186.     /**
  187.      * 获取运行时长
  188.      */
  189.     this.getRunTime = function() {
  190.         if (lastHeartbeatTime) {
  191.             var now = new Date();
  192.             return now - lastHeartbeatTime;
  193.         }
  194.         return 0;
  195.     };
  196. }

  197. /**
  198. * 任务进度追踪器
  199. * 解决:多步骤任务,实时显示执行进度
  200. */
  201. function ProgressTracker() {
  202.     var totalSteps = 0;
  203.     var currentStep = 0;
  204.     var stepNames = [];
  205.     var startTime = null;
  206.    
  207.     /**
  208.      * 初始化任务
  209.      * @param {Array} steps - 步骤名称数组
  210.      */
  211.     this.init = function(steps) {
  212.         stepNames = steps;
  213.         totalSteps = steps.length;
  214.         currentStep = 0;
  215.         startTime = new Date();
  216.         
  217.         print.log("");
  218.         print.log("========== 任务进度追踪 ==========");
  219.         print.log("总步骤: " + totalSteps);
  220.         print.log("步骤列表: " + steps.join(" → "));
  221.         print.log("==================================");
  222.         print.log("");
  223.         
  224.         return this;
  225.     };
  226.    
  227.     /**
  228.      * 更新进度
  229.      * @param {String} stepName - 当前步骤名称
  230.      * @param {String} status - 状态 (start/complete/error)
  231.      */
  232.     this.update = function(stepName, status) {
  233.         if (status === "start") {
  234.             currentStep++;
  235.             var progress = Math.floor((currentStep / totalSteps) * 100);
  236.             print.log("[进度 " + progress + "%] ▶ 开始: " + stepName);
  237.         } else if (status === "complete") {
  238.             print.log("[进度 " + Math.floor((currentStep / totalSteps) * 100) + "%] ✓ 完成: " + stepName);
  239.         } else if (status === "error") {
  240.             print.log("[进度 " + Math.floor((currentStep / totalSteps) * 100) + "%] ✗ 错误: " + stepName);
  241.         }
  242.         
  243.         return this;
  244.     };
  245.    
  246.     /**
  247.      * 完成任务
  248.      */
  249.     this.finish = function() {
  250.         var endTime = new Date();
  251.         var duration = endTime - startTime;
  252.         
  253.         print.log("");
  254.         print.log("========== 任务完成 ==========");
  255.         print.log("总耗时: " + duration + "ms (" + (duration/1000).toFixed(2) + "秒)");
  256.         print.log("完成步骤: " + currentStep + "/" + totalSteps);
  257.         print.log("==============================");
  258.         print.log("");
  259.         
  260.         return this;
  261.     };
  262. }

  263. // ==================== 实用场景示例 ====================

  264. /**
  265. * 场景1:带超时保护的页面等待
  266. * 实际问题:等待某个元素出现,但不能无限等待
  267. */
  268. function example_WaitForElementWithTimeout() {
  269.     print.log("");
  270.     print.log("【场景1】带超时保护的页面等待");
  271.     print.log("----------------------------------------");
  272.    
  273.     var timeoutCtrl = new TimeoutController();
  274.    
  275.     // 模拟等待某个元素出现
  276.     timeoutCtrl.start(5000, function() {
  277.         print.log("超时处理:元素未找到,执行备选方案");
  278.         // 这里可以执行备选逻辑,比如刷新页面、点击其他按钮等
  279.     });
  280.    
  281.     // 模拟查找元素的操作
  282.     runTime.setTimeout(function() {
  283.         // 假设找到了元素
  284.         print.log("✓ 找到目标元素!");
  285.         timeoutCtrl.complete(); // 标记完成,清除超时
  286.         
  287.         // 继续后续操作...
  288.     }, 2000);
  289.    
  290.     sleep.second(秒=6);
  291. }

  292. /**
  293. * 场景2:带重试的网络请求
  294. * 实际问题:网络不稳定,请求可能失败,需要自动重试
  295. */
  296. function example_RetryNetworkRequest() {
  297.     print.log("");
  298.     print.log("【场景2】带重试的网络请求");
  299.     print.log("----------------------------------------");
  300.    
  301.     var retryCtrl = new RetryController();
  302.     retryCtrl.configure(3, 2000); // 最多重试3次,间隔2秒
  303.    
  304.     var attemptCount = 0;
  305.    
  306.     retryCtrl.execute(
  307.         function() {
  308.             // 模拟网络请求(前两次失败,第三次成功)
  309.             attemptCount++;
  310.             print.log("  发起网络请求... (尝试#" + attemptCount + ")");
  311.             
  312.             if (attemptCount < 3) {
  313.                 print.log("  ✗ 请求失败:网络超时");
  314.                 return false;
  315.             } else {
  316.                 print.log("  ✓ 请求成功!");
  317.                 return true;
  318.             }
  319.         },
  320.         "数据上传",
  321.         function() {
  322.             // 成功回调
  323.             print.log("→ 继续处理响应数据...");
  324.         },
  325.         function() {
  326.             // 失败回调
  327.             print.log("→ 所有重试都失败了,记录错误日志");
  328.         }
  329.     );
  330.    
  331.     sleep.second(秒=10);
  332. }

  333. /**
  334. * 场景3:后台任务心跳监控
  335. * 实际问题:长时间运行的脚本,需要确认它还在正常工作
  336. */
  337. function example_HeartbeatMonitoring() {
  338.     print.log("");
  339.     print.log("【场景3】后台任务心跳监控");
  340.     print.log("----------------------------------------");
  341.    
  342.     var heartbeat = new HeartbeatMonitor();
  343.    
  344.     // 启动心跳监控
  345.     heartbeat.start(3000, function(count) {
  346.         // 每次心跳时可以执行一些检查
  347.         if (count % 3 === 0) {
  348.             print.log("  [定期自检] 内存正常、网络连接正常");
  349.         }
  350.     });
  351.    
  352.     // 模拟后台任务运行
  353.     print.log("后台任务正在运行...");
  354.     sleep.second(秒=10);
  355.    
  356.     // 停止心跳
  357.     heartbeat.stop();
  358. }

  359. /**
  360. * 场景4:多步骤任务进度追踪
  361. * 实际问题:复杂的自动化流程,需要清楚知道执行到哪一步了
  362. */
  363. function example_ProgressTracking() {
  364.     print.log("");
  365.     print.log("【场景4】多步骤任务进度追踪");
  366.     print.log("----------------------------------------");
  367.    
  368.     var tracker = new ProgressTracker();
  369.    
  370.     // 定义任务步骤
  371.     tracker.init([
  372.         "打开应用",
  373.         "登录账号",
  374.         "导航到目标页面",
  375.         "执行数据采集",
  376.         "保存数据",
  377.         "退出应用"
  378.     ]);
  379.    
  380.     // 模拟执行各个步骤
  381.     var steps = [
  382.         {name: "打开应用", delay: 1},
  383.         {name: "登录账号", delay: 2},
  384.         {name: "导航到目标页面", delay: 1},
  385.         {name: "执行数据采集", delay: 3},
  386.         {name: "保存数据", delay: 1},
  387.         {name: "退出应用", delay: 1}
  388.     ];
  389.    
  390.     for (var i = 0; i < steps.length; i++) {
  391.         var step = steps[i];
  392.         
  393.         // 开始步骤
  394.         tracker.update(step.name, "start");
  395.         
  396.         // 模拟步骤执行
  397.         sleep.second(秒=step.delay);
  398.         
  399.         // 完成步骤
  400.         tracker.update(step.name, "complete");
  401.     }
  402.    
  403.     // 任务完成
  404.     tracker.finish();
  405. }

  406. /**
  407. * 场景5:综合应用 - 完整的自动化流程
  408. * 结合所有工具,实现一个健壮的自动化脚本
  409. */
  410. function example_CompleteAutomation() {
  411.     print.log("");
  412.     print.log("【场景5】综合应用 - 完整的自动化流程");
  413.     print.log("----------------------------------------");
  414.     print.log("这个场景展示了如何组合使用所有工具");
  415.     print.log("构建一个健壮、可靠的自动化脚本");
  416.     print.log("");
  417.    
  418.     // 1. 进度追踪
  419.     var tracker = new ProgressTracker();
  420.     tracker.init(["初始化", "执行任务", "清理资源"]);
  421.    
  422.     // 2. 心跳监控(确保脚本不会卡死)
  423.     var heartbeat = new HeartbeatMonitor();
  424.     heartbeat.start(5000);
  425.    
  426.     // 步骤1:初始化
  427.     tracker.update("初始化", "start");
  428.    
  429.     var timeoutCtrl = new TimeoutController();
  430.     timeoutCtrl.start(3000, function() {
  431.         print.log("初始化超时,使用默认配置");
  432.     });
  433.    
  434.     sleep.second(秒=1);
  435.     timeoutCtrl.complete();
  436.     tracker.update("初始化", "complete");
  437.    
  438.     // 步骤2:执行任务(带重试)
  439.     tracker.update("执行任务", "start");
  440.    
  441.     var retryCtrl = new RetryController();
  442.     retryCtrl.configure(2, 1500);
  443.    
  444.     retryCtrl.execute(
  445.         function() {
  446.             print.log("  执行核心任务...");
  447.             return true; // 模拟成功
  448.         },
  449.         "核心任务",
  450.         function() {
  451.             print.log("  任务执行成功");
  452.         },
  453.         function() {
  454.             print.log("  任务执行失败");
  455.         }
  456.     );
  457.    
  458.     sleep.second(秒=3);
  459.     tracker.update("执行任务", "complete");
  460.    
  461.     // 步骤3:清理资源
  462.     tracker.update("清理资源", "start");
  463.    
  464.     heartbeat.stop();
  465.    
  466.     sleep.second(秒=1);
  467.     tracker.update("清理资源", "complete");
  468.     tracker.finish();
  469.    
  470.     print.log("✓ 自动化流程完成!");
  471. }

  472. // ==================== 主演示流程 ====================
  473. function main() {
  474.     print.log("╔════════════════════════════════════════╗");
  475.     print.log("║   AIWROK 脚本任务管理器 - 实用工具集  ║");
  476.     print.log("║                                       ║");
  477.     print.log("║  解决脚本开发的常见痛点:              ║");
  478.     print.log("║  • 防止无限等待导致卡死               ║");
  479.     print.log("║  • 自动重试提高稳定性                 ║");
  480.     print.log("║  • 心跳监控确保正常运行               ║");
  481.     print.log("║  • 进度追踪方便调试                   ║");
  482.     print.log("╚════════════════════════════════════════╝");
  483.    
  484.     sleep.second(秒=2);
  485.    
  486.     // 演示各个场景
  487.     example_WaitForElementWithTimeout();
  488.     example_RetryNetworkRequest();
  489.     example_HeartbeatMonitoring();
  490.     example_ProgressTracking();
  491.     example_CompleteAutomation();
  492.    
  493.     print.log("");
  494.     print.log("╔════════════════════════════════════════╗");
  495.     print.log("║         演示完成!                     ║");
  496.     print.log("╚════════════════════════════════════════╝");
  497.     print.log("");
  498.     print.log("这些工具可以直接用到你的脚本中:");
  499.     print.log("");
  500.     print.log("1. TimeoutController - 超时保护");
  501.     print.log("   用途:等待元素、网络请求等操作的超时控制");
  502.     print.log("   示例:var tc = new TimeoutController();");
  503.     print.log("         tc.start(5000, onTimeout);");
  504.     print.log("         // ... 执行操作 ...");
  505.     print.log("         tc.complete();");
  506.     print.log("");
  507.     print.log("2. RetryController - 自动重试");
  508.     print.log("   用途:网络请求、节点查找等可能失败的操作");
  509.     print.log("   示例:var rc = new RetryController();");
  510.     print.log("         rc.configure(3, 2000);");
  511.     print.log("         rc.execute(operation, '操作名', onSuccess, onFail);");
  512.     print.log("");
  513.     print.log("3. HeartbeatMonitor - 心跳监控");
  514.     print.log("   用途:长时间运行的脚本,定期检查是否正常");
  515.     print.log("   示例:var hb = new HeartbeatMonitor();");
  516.     print.log("         hb.start(5000, onHeartbeat);");
  517.     print.log("         // ... 运行任务 ...");
  518.     print.log("         hb.stop();");
  519.     print.log("");
  520.     print.log("4. ProgressTracker - 进度追踪");
  521.     print.log("   用途:多步骤任务,实时显示执行进度");
  522.     print.log("   示例:var pt = new ProgressTracker();");
  523.     print.log("         pt.init(['步骤1', '步骤2']);");
  524.     print.log("         pt.update('步骤1', 'start');");
  525.     print.log("         // ... 执行 ...");
  526.     print.log("         pt.update('步骤1', 'complete');");
  527.     print.log("         pt.finish();");
  528.     print.log("");
  529.     print.log("把这些类复制到你的脚本开头,就能直接使用了!");
  530. }

  531. // ==================== 执行入口 ====================
  532. main();
复制代码







欢迎光临 B2B网络软件 (http://bbs.niubt.cn/) Powered by Discuz! X3.2