首先说一下我的想法来源,之前有做一个功能就是点击一个按钮后台生成几张pdf文件,这种耗时的操作有个弊端就是前台不能很直观的看到后台的进度情况,特别是量大的情况,就感觉页面死了一样,只能看到浏览器上方的小圆圈在转,如果是异步操作似乎连小圆圈都没有。
数据模拟是这样的,前台发送请求,后台定一个循环,比如从100减到0,每一秒循环一次,每次循环都把这个最新的数字发送给前台,直到循环结束。
首先我没有想到怎么去实现,而是想到去网上找现成的,找了好久都没有找到一个简单易用的,这么简单的一个问题感觉答案却不简单,实在没学会怎么传,在此我想问点问题:
1.后台可以主动发消息给前台不?
2。后台php或者说前台js有没有监听事件,比如:实时监听某个文件夹的变动,文件的变动,或者监听时钟这种,我记得Android可以,有什么广播这种。(突然想到网页上的实时聊天是怎么弄得呀?思路是什么?)
回到正题
第一个坑:
最开始我是这么实现的:
前台用ajax发送请求,这是后台收到请求,开始循环,每循环一次 echo 一个数据,结果当然是不行的,如果直接echo一个数据可以,放到循环里面就不行了,我也试过不用循环,比如这样:
echo 10;
sleep(1);
echo 20;
就在三行代码,结果返回了1020;
失败!!!
第二个坑:
用一个文件中转,就是后台循环的时候 比如每秒中循环一个,每次循环就往一个文件里面更新数据
file_put_contents("load.txt", $i%100);
然后前台js也每秒中去读取这个文件的内容,
结果遇到两个问题:
1.js读取这个文件的操作我在网上看了没看懂,照着写出来总是报错也不知道为什么报错,
2.这个文件是在服务器端,也不知道能读到不,因为读本地文件都没有弄会。
失败!!!
突然灵机一动 最终实现是这样的
前台同时发送两个请求,即 一个方法里面 并行着两个ajax,第一个ajax去访问比如control.php用来触发循环,每次循环还是往一个文件如load.txt写入数据,另个ajax写到循环setInterval中去定时访问另一个后台如load.php。
load.php去读取load.txt的文本 echo 给前台,这样就基本实现了获得后台进度的情况。
不过这种实现我单纯的想出来的没有找到参考,感觉方式比较勉强,服务器访问太频繁,不过确实能达到效果,就做个笔记吧,希望大家指点一下,还有给一下更好的实现。
index.html
!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>操作进度</title> <link rel="stylesheet" href="https://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body> <button class='btn btn-info' onclick="send()" >这里是按钮</button> <div style="height:50px;width:300px;border:1px solid #000;"> <div id='bar' style="height:50px;background-color: red;width:10%"> </div> </div> </body> <script> function send() { $.ajax( { url:'control.php', async:true, type:'GET', success:function(data){ } } ); setInterval(function(){ $.ajax({ url:'load.php', type:'GET', success:function(data){ $("#bar").css({width:data+"%"}); } }); },1000); }</script> </html>
load.php
<?php echo file_get_contents('load.txt');
control.php
<?php $i = 10; while (true) { file_put_contents("load.txt", $i%100); $i += 10; sleep(2); if($i > 200) break; } echo 0;
求指点,,我暂时不知道正常的实现方式该怎样了、、、、、