简单重构可以是以下这样的,我假设你渲染的页面是 app/views/players.html.erb
:
<!-- app/views/players.html.erb -->
<%= form_for(:player) do |f| %>
<%= f.label :sum_player, "游戏人数"%>
<%= f.number_field :sum_player, in: 1..12, class: 'form-control',id:"sumofplayer" %>
<% end %>
<button type="button" id="myButton" class="btn btn-primary" >分配角色</button>
<!-- 这个地方的代码可以去掉
<p>
<%= link_to "A post", playerrole_path, remote: true ,method: :post,class: "btn btn-primary"%>
</p>
-->
<div id="role-container">
<div id="player_role"></div>
<!-- 这个按钮固定就好了,没必要像原来一样动态添加 -->
<button type="button" id="myButton" class="btn btn-primary" >确定角色</button>
</div>
<script>
// 全局变量命名空间
App ||= {};
// 这里预先加载角色相关信息,以供后边脚本使用
App.playerRoles = <%== render 'games/player_role', :player => [1,'bandman',3,4] %>;
</script>
而跟这个页面配套的脚本应该是同时下载的,里边的内容改为:
$ ->
$playerCountInput = $('#sumofplayer')
if $playerCountInput.length
badManNumber = 2
$playerRole = $('#player_role')
gRandomArr = ( arr, num_of_badman ) ->
for i in [0...num_of_badman]
# 直接用随机下标就可以了,原来的方式还得整个数组重新排序,没必要
randomIndex = parseInt(Math.random() * arr.length)
arr[randomIndex] = 'badman'
make_role_for_players = (content, num_of_badman) ->
arr = [] # arr 的初始化放在函数里就好了,没必要放外边
$playerRole.empty(); # 用 $.fn.empty() 方法更语义化,比起 $.fn.html("") 更舒服
if content
for num in [0...content]
arr.push( num )
gRandomArr(arr, num_of_badman)
for x,index in arr
$playerRole.append('<p>' + index + (if arr[index] == 'badman' then '内奸' else '') + '</p>');
$playerCountInput.on "change", (e)->
make_role_for_players $playerCountInput.val(), badManNumber
整个过程就没有任何需要往后端发送请求的必要,以上代码仅为示例,我没法运行,你自己看看吧。还不明白的话,就只能奉劝楼主老老实实重新认真学习基础知识了。
#2 楼 @zix 没有。这个问题本身不复杂也不深奥,是你没有理清楚一个请求的生命历程而已,混淆了其中的区别而已。感觉楼主需要好好阅读一下 《一次完整的 HTTP 事务是怎样一个过程?》这样的文章。
楼主没有理解渲染的机制。erb 是服务器端渲染的模板,渲染后的 HTML 下载到浏览器,浏览器才开始渲染 HTML 跟解析 js。你这种问题是倒过来的流程了,怎么可能实现呢?或者你用 ajax 的方式,先得到一个 javascript 数组,然后通过 ajax 请求将数组作为参数提交给后端,后端按照你给的参数渲染 HTML 片段,你再用 js 将这个片段替换到你想替换的位置。
无敌,无敌是多么寂寞!
@lgn21st 我自己重新看了一遍,感觉图片都没有修好,我先取消分享了,这段时间慢慢认真修一遍再重新发出来吧。
#2 楼 @michael_roshen 贴 nginx 配置吧
不过权重大小应该不影响 worker 的执行吧
不影响 你说没有跑?你检查时的时间离你期待执行的时间过去多久了?另外,sidekiq 的 schedule 不是按精准时间执行的。可能偏离几十秒都是有可能的。
我上周对 Sidekiq 任务调度有过简单的研究,这段时间正打算写篇文章介绍下。
ruby-china 熊猫牌拖鞋、方便面、短裤、内衣内裤、抱枕、双肩包
#10 楼 @Catherine .org
域名代表 organization,一般用于非公益性组织。哈哈,拿来卖东西就不好了。
真高效!大赞!
#4 楼 @danielglh 呃,我其实都没来得及修复白平衡错误。。。
首图是我拍的吗?
#6 楼 @Catherine 帮你 @huacnlee ,深藏功与名
你是只想回滚单个资源,而不是整个外层 transaction?
既然是自己的改动,为什么还要合并回 Ruby China?
不过有个小问题,这个 gem 里有 js 脚本,现在用的 ready 事件,在新的 Turbolinks 5 中跳转不好使,需要使用 turbolinks:load,但是这样以来对之前的 Rails 应用应该也有影响了。
是不是可以做个判断?
乱
@happyming9527 @nowherekai 为了直观理解,我写了个示例代码,可以看下:
# test file
array = [10]
threads = []
i = 1000 # 主线程中变量
former_i = []
latter_i = []
array.each do |i| # block 变量
threads << Thread.new do
10.times { former_i << (i += 1) }
end
end
array.each do |i| # block 变量
threads << Thread.new do
10.times { latter_i << (i -= 1) }
end
end
threads.each(&:join) # 在继续执行前等待其他线程执行完毕
puts "former_i: #{former_i}"
puts "latter_i: #{latter_i}"
puts "i in main thread: #{i}"
运行结果是:
据此,可以得出:
.each
方法调用中的 block 中的变量 i
都没有污染主线程中的变量;i
引用的是各自上下文代码块里的 i
变量,并非之前理解的主线程变量;i
在整个运行过程中未被修改,仍然是 1000
;i
变量是有作用域保护,互无关系。#14 楼 @happyming9527 不会,两个 i 是各自对应的 block 的局部变量,代码块也有自己的作用域,线程里引用的变量 i 是受 .each
的代码块的作用域保护的,与主线程中另一个代码块中的 i
不是同一个变量了。
#12 楼 @nowherekai 不会有问题,前面有 join,主线程会等待前面线程都执行完才接着执行,如果没有 join,你说的就是对的了
redis 或者 memcached 都是正解,没必要自己再去折腾进程间通信的问题。
这个应该是只有在 autoload(线程不安全)的时候才会报的错误,按理说在 production
下应该是不会报错。一般为了避免这种错误,我都是在线程创建的代码之前先手动触发加载,虽然丑陋,但是好用:
UserKid # do nothing, just for trigger loading
Thread.new do
UserKid.do_something()
end
Thread.new do
UserKid.do_something_else()
end