在下面的最小示例中,旧内容的替换通过 setTimeout 延迟,以便让用户有时间完成查看。与此同时,正在准备新内容,以避免在执行可能代价高昂的任务时阻塞用户界面。
var div = document.getElementById('wrapper');
var newContent = document.createElement('ul');
setTimeout(function() {
var header = div.firstElementChild;
header.innerHTML = 'New Content';
header.nextElementSibling.remove();
div.appendChild(newContent);
}, 2000);
// Make new content while we wait
[1, 10, 100, 1000].forEach(function(x) {
var li = document.createElement('li');
li.innerHTML = 'Factorial of ' + x + ' is ' + factorial(x);
newContent.appendChild(li);
});
function factorial(num) {
if (num === 0) {
return 1;
} else {
return (num * factorial(num - 1));
}
}<div id='wrapper'>
<h1>Old content</h1>
<p>Read it before it's gone.</p>
</div>
我对这种方法的担忧是,它似乎无法处理 newContent 在替换即将发生时未准备就绪的情况。我也不确定这种方法是否会阻塞用户界面,或者 setTimeout 使用的任务是否会同时执行。
如何确保用户界面在执行可能代价高昂的任务时不会被阻塞并在完成后立即使用它?
最佳答案
长时间运行的计算会阻塞浏览器,这绝不是一个好主意。因此,你应该把它放在网络 worker 中。
如今,使用 promises 等异步工具编写异步代码是更好的做法。这是一种通用的伪代码级方法:
// Create a promise which fulfills after some # of ms.
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Create the worker, kick it off, and
// return a promise which fulfills when the worker reports a result.
function waitWorker() {
const worker = new Worker('factorial.js');
worker.postMessage([1, 10, 100, 1000]);
return new Promise(resolve =>
worker.addEventListener('message', event => resolve(event.data))
);
}
// Wait for both the worker to complete and the two seconds to elapse.
// Then output the data.
Promise.all([timeout(2000), waitWorker()])
.then(values => output(values[1]);
编写 worker 留作练习。
如果您的环境支持,您还可以使用异步函数更清楚地表达这一点,如下所示:
async function calcAndWait() {
const result = waitWorker(); // Kick off computation.
await timeout(ms); // Wait for two seconds.
output(await result); // Wait for computation to finish and output.
}
关于javascript - 在等待时执行延迟函数所依赖的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39666416/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru