【发布时间】:2015-03-03 00:57:58
【问题描述】:
我正在使用PhantomJS + d3 将美国邮政编码的地图呈现为后端进程。渲染和邮政编码计算需要很长时间,以至于将 html 和 d3 js 放入浏览器需要一分钟才能加载并导致其他问题,因此我们将其移至后端。
如果我通过 curl 向 PhantomJS 启动的节点服务器发送一个请求,没问题。如果我将我们的多个地图请求间隔大约 15 秒,也没有问题。但是,如果我很快启动几个 curl 请求,渲染的图像最终看起来是一样的(也就是将相同的图像写入多个文件。)这是幻像脚本:
var 端口, 服务器, 服务, 页, 网址, svgDrawer;
fs = require('fs');
port = 9494;
server = require('webserver').create();
page = require('webpage').create();
service = server.listen(port, function (request, response) {
var drawerPayload = null;
try{
drawerPayload=JSON.parse(request.post);
} catch(e){
response.statusCode = 417;
response.write("Error : Invalid Input JSON");
response.close();
return;
}
url = 'file:///' + fs.absolute('./'+drawerPayload.inFile);
page.open(url, function (status) {
if(status=="success"){
page.evaluate(function(data){
$("body").on( "click", data, chartBuilder );
$("body").click();
var maxtimeOutMillis = 15000,
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
condition = $("svg.chart").hasClass("done"); //< defensive code
} else {
if(!condition) {
clearInterval(interval)
} else {
page.render(drawerPayload.outFile);
clearInterval(interval); //< Stop this interval
}
}
}, 250); //< repeat check every 250ms
});
response.statusCode = 200;
} else {
response.statusCode = 404;
response.write("Not Found"+url);
}
response.close();
return;
});
page.onError = function (msg, trace) {
console.log(msg);
trace.forEach(function(item) {
console.log(' ', item.file, ':', item.line);
})
response.statusCode = 417;
response.write("Error : "+msg);
response.close();
return;
}
});
html+d3 看起来像这样:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.zip {
stroke: none;
}
.chart {
fill: white;
width: 1000px;
height: 500px;
}
</style>
<body>
<div id="chart-container">
<svg class="chart"></svg>
</div>
</body>
<script src="./jquery-min.js"></script>
<script src="./d3.min.js"></script>
<script type="text/javascript" src="http://d3js.org/topojson.v1.min.js"></script>
<script>
function chartBuilder(e){
var zip_data = e.data;
$.getJSON("zips_us_topo.json", function(us){
console.log("rendering...\n");
var width = 1000;
var height = 500;
var projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geo.path().projection(projection);
var color = d3.scale.log().domain([1,zip_data.max+1]).range(["#cccccc","#f63337"]);
var svg = d3.select("svg.chart")
.attr("width", width)
.attr("height", height)
.style({margin: "10px 100px"})
.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(us, us.objects.zip_codes_for_the_usa).features)
.enter()
.append("path")
.attr("class", "zip")
.style({fill: function(d){
return color(zip_data.counts[d.properties.zip] ? zip_data.counts[d.properties.zip]+1 : 1);
}})
.attr("d", path);
svg.classed("done", true);
});
}
</script>
如果请求都同时卷曲,则看起来它正在将一张图像写入所有输出文件。 PhantomJS 是为每个请求创建一个新页面,还是每次都加载相同的请求?
【问题讨论】: