jjzjj

php - 导致两件事并行加载?

coder 2024-01-02 原文

我正在编写一些执行大量处理然后生成结果报告的 PHP。以前它会定期执行 flush(),但我们正在转向 Zend Framework,不能再这样做了。相反,我希望在生成报告时更新某种状态显示。所以我制作了一个在 iframe 中加载的进度条,将共享内存添加到进度条更新操作和报告生成操作,并通过 xmlhttprequest 加载输出。这一切都很好。我的问题是浏览器想要连续而不是并行地执行这两个请求,所以它会请求进度条,然后阻塞直到进度条完成,然后才会请求实际输出。这意味着该过程永远不会结束,因为真正的工作永远不会开始。

我整个上午都在寻找解决这个问题的方法,但一无所获。 有什么方法可以建立两个连接,还是我搞砸了?

我的下一个 Action 是将处理进一步分解,让状态更新 Action 完成实际工作,保存结果,然后使用另一个 Action 来转储它。这将非常痛苦,我想避免它。

编辑:这是请求的javascript:

    function startProgress()
    {
        var iFrame = document.createElement('iframe');
        document.getElementsByTagName('body')[0].appendChild(iFrame);
        iFrame.id = 'progressframe';            
        iFrame.src = '/report/progress';
    }

    function Zend_ProgressBar_Update(data)
    {
        document.getElementById('pg-percent').style.width = data.percent + '%';
        document.getElementById('pg-text-1').innerHTML = data.text;
        document.getElementById('pg-text-2').innerHTML = data.text;
    }

    function Zend_ProgressBar_Finish()
    {
        document.getElementById('pg-percent').style.width = '100%';
        document.getElementById('pg-text-1').innerHTML = 'Report Completed';
        document.getElementById('pg-text-2').innerHTML = 'Report Completed';
        document.getElementById('progressbar').style.display = 'none'; // Hide it
    }

    function ajaxTimeout(){
        xmlhttp.abort();
        alert('Request timed out');
    }

    var xmlhttp;
    var xmlhttpTimeout;

    function loadResults(){
        if (window.XMLHttpRequest){
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }else{
            // code for IE6, IE5
            xmlhttp=new ActiveXObject(\"Microsoft.XMLHTTP\");
        }
        xmlhttp.open(\"POST\",\"/report/output\",true);
        xmlhttp.onreadystatechange=function(){
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                clearTimeout(xmlhttpTimeout);
                document.getElementById('report-output').innerHTML=xmlhttp.responseText;
            }
        }
        var xmlhttpTimeout=setTimeout(ajaxTimeout,600000); // Ten minutes
        xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xmlhttp.send('".file_get_contents("php://input")."');           
    }

这是从以下 onload 脚本调用的:

onload="startProgress(); setTimeout(loadResults,1000);"

问题不在 Javascript 中。如果您将 alert() 放在那里,警报将在正确的时间触发,但浏览器会延迟第二个 http 事务,直到第一个完成。


谢谢大家的意见。

在我们的开发计划允许的时间范围内,我没有对此给出满意的答案。似乎每个常见的浏览器都希望在与该站点进行多次交易时重新使用该站点的现有连接。我想不出的任何东西都会导致浏览器按需启动并行连接。每当有来自同一服务器的两个请求时,客户端希望以串行方式执行它们。

我最终将处理分解成多个部分并将其移动到状态栏更新操作中,将报告输出保存到服务器上的一个临时文件中,然后使状态栏完成函数启动 xmlhttprequest 以加载结果。 output Action 只是吐出临时文件的内容,然后将其删除。

最佳答案

使用两个异步 ajax 可以达到目的。对于第一个 ajax 请求,您应该通过调用 php-cli 来启动进程以在后台深处执行实际工作(因此它不会过期或取消)并返回进程的 ID(任务)。现在,当您拥有进程 ID 时,您可以启动周期性的 ajax 来显示所创建的进程。

制作一个包含process_id、state、user的db表也不是坏事。在这种情况下,即使用户在进程运行时关闭浏览器,进程也会继续直到完成。用户可以重新访问该页面并查看完成百分比,因为在 cli 中运行的进程会将进度保存到 db 表中。

关于php - 导致两件事并行加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6231276/

有关php - 导致两件事并行加载?的更多相关文章

  1. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  4. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  5. ruby - 带括号和 splat 运算符的并行赋值 - 2

    我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow

  6. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  7. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  8. ruby - 从另一个私有(private)方法中使用 self.xxx() 调用私有(private)方法 xxx,导致错误 "private method ` xxx' called” - 2

    我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是

  9. ruby - 为什么 return 关键字会导致我的 'if block' 出现问题? - 2

    下面的代码工作正常:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson)do|key,oldv,newv|ifkey==:aoldvelsifkey==:bnewvelsekeyendendputskerson.inspect但是如果我在“ifblock”中添加return,我会得到一个错误:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson

  10. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

随机推荐