
function start() { var screen = captureScreen(); // 出现弹框, 干掉弹框 if (screen.find(ALERT_BUTTON) { click(ALERT_CLOSE_BUTTON); start(); } // 如果有返回按钮, 点击返回 if (screen.find(BACK_BUTTON) { click(BACK_BUTTON); start(); } // 如果不在首页(首页没有高亮选中), 点击回到首页 if (screen.find(HOME_BUTTON_UNHIGHLIGHT) { click(HOME_BUTTON_UNHIGHLIGHT); start(); } // 在首页了, 有“喜欢按钮” if (screen.find(LIKE_BUTTON) { click(LIKE_BUTTON); swipeNextVideo(); sleep(5000); start(); } } setInterval(function() { if (currentPackage() !== 'PACKAGE_NAME') { launch('PACKAGE_NAME'); } }, 1000*60*10) // 10 分钟检查一次程序是否被杀死, 程序不在运行就重新打开 start(); 以上是脚本程序的大概逻辑:
打开某视频软件, 如果有弹框, 干掉弹框, 如果不在首页, 返回首页, 刷视频点赞, 然后继续下一轮
程序使用了递归, 如果运行时间过长, 内存占用会变大. 有什么方法可以优化这一点?
我尝试过使用 while 和 continue:
while (true) { if (condition1) { doSometing2(); continue; } if (condition2) { doSometing2(); continue; } .. } 但死循环会让外面的 setInterval 不被执行.
还尝试过使用 generator 来做, 配合 redux-saga, 但这个框架不支持 es6, 在使用 babel 转译时候, 遇到一堆问题, 就跑不通了.
所以除了 以上几种方法, 还有什么方法可以优化吗?
1 MegrezZhu 2021-12-19 18:28:42 +08:00 我想了很多,写了一点伪代码,然后删掉了。 为什么不直接五分钟重启一次脚本呢[狗头] |
2 ch2 2021-12-19 18:29:50 +08:00 看了一下,你应该使用定时任务而不是递归来完成你想要的操作 加一个全局变量 working ,start 开始的时候设置 working 为 true ,结束的时候设置为 false 然后定时每隔 10 秒触发一次 start ,如果正在 working 直接 return 再把 start 函数里把递归调用自己的全部注释掉 |
3 lscho 2021-12-19 18:34:09 +08:00 递归引起的堆栈溢出改成尾递归或者匿名函数都可以解决。但是你的代码里最明显的是 setInterval 问题,setInterval 长时间运行会内存增大不是常识吗?先把这个解决了再看是不是递归的问题吧。 |
4 ethusdt OP @MegrezZhu 额, 上面只是个 demo, 实际代码比这复杂的多, 要抢红包 /抢东西, 需要每 300 毫秒截图判断, 重启脚本这代价太大了. @ch2 哦. 知道了, 我太愚蠢了. 可以直接 setInterval(start, 500) 来做无限循环. 本来没想用这方法是考虑到有这情形: function start() { ... if(cond) callA(); ... } function callA() { var someVars = ...; doMainTask(); setTimeout(function() { // 10 秒钟没干完,直接退出 closureUseVar(someVars); cancelMainTask(); exitPage(); start(); // here 又递归了 }, 10000) } (v2ex 回复会把代码缩进吃掉) 这样, 按你的方法, 加一个 flag 控制, 使用 setInterval 来进行无限循环就可以了. 在使用到递归的地方 直接设置 `flag = !flag`; |
5 ethusdt OP @lscho setInterval 长时间运行为啥会增大内存? 我没考虑到这个问题. interval 结束函数都被 GC 了吧 ? |
6 ethusdt OP |
7 ethusdt OP |
8 rpman 2021-12-19 22:53:09 +08:00 Looping 的话应该 sleep 一下吧 或者可以写成 Event driven |
10 2i2Re2PLMaDnghL 2021-12-20 09:47:37 +08:00 @lscho 尾调用优化目前只有 safari 或者用 babel 支持吧 |
11 lscho 2021-12-20 10:44:51 +08:00 @2i2Re2PLMaDnghL babel 只是把浏览器不支持的语法转为支持的,既然他能转,那就能写出来啊 |
12 2i2Re2PLMaDnghL 2021-12-20 11:17:17 +08:00 @lscho 哦你是说手写 TCO 啊 其实 OP 主题里的 start 把后续 if 全转 else if 并把 start() 换成 return start() 的话,所有 start() 就都在尾位置上了,我以为你是指这个…… |
13 iPhone12 2021-12-20 12:40:38 +08:00 via iPhone 1 中可以将 sleep 去掉,最后再 setTimeout(start, 0 或者 500),不会爆栈也不会阻塞后面的 setInterval |
14 Fatpandac 2021-12-20 13:53:10 +08:00 ``` // 在首页了, 有“喜欢按钮” if (screen.find(LIKE_BUTTON) { ``` 发现 bug ,少了个右括号:joy: |