我一直沿用亚当·简斯(Adam Janes)的编排tutorial。
此代码块加载了数据
var promises = [
d3.json("https://d3js.org/us-10m.v1.json"),
d3.tsv("unemployment.tsv", function(d) { unemployment.set(d.id, +d.rate); })
]
Promise.all(promises).then(ready)
就绪定义为
function ready([us]) {
svg.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features)
.enter().append("path")
.attr("fill", function(d) { return color(d.rate = unemployment.get(d.id)); })
.attr("d", path)
.append("title")
.text(function(d) { return d.rate + "%"; });
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("class", "states")
.attr("d", path);
}
我将此顺序理解为
第一-创建一个名为promises的数组,其中第一项是从该link解析的json,第二项是具有失业文件中ID /值对的映射
second-在promise变量中获取所有promise,如果成功,则触发函数准备就绪,如果失败,则不执行任何操作
如果是正确的话,那么相对于这种东西有什么优势呢?我是用伪代码编写的,因为我是新手
var promises = [
d3.json("https://d3js.org/us-10m.v1.json"),
d3.tsv("unemployment.tsv", function(d) { unemployment.set(d.id, +d.rate); })
]
if(promises == 'SUCCESS'){ function(ready) };
请注意,由于javascript是单线程的,因此我阅读了有关promise及其优势的信息。我问这个问题是因为这并没有使我感到异步发生了什么,因此在两种情况下代码都必须加载promises数组。
答案 0 :(得分:3)
d3.json()
和d3.tsv()
都是异步网络调用。这些诺言将在通话完成后解决。您的伪代码不起作用,因为if
将在异步调用完成后立即运行,而不是在完成后立即运行。
承诺是一种表达方式:“执行此操作需要一段时间,然后完成后再对其结果进行处理”。 (如注释中所指出的,这是一个简化的定义,但可能足以开始使用。)同步的版本是“执行此操作需要一段时间,然后立即尝试对结果进行操作(即还没到)。”
Promise.all(promises).then(ready);
在这种情况下,您实际上有一个包含在另一个承诺中的承诺-两个d3
调用每个都是一个承诺,然后Promise.all()
围绕着两个都包装了另一个承诺,这将等到两个内部元素在触发then()
之前是完整的。
这与javascript是单线程无关;它只是改变事件的顺序。要澄清:
console.log("Before promises");
Promise.all(promises).then(function() {
console.log("Promises have resolved");
});
console.log("After promises");
将导致以下输出:
> Before promises
> After promises
> Promises have resolved
答案 1 :(得分:2)
让我惊讶的是异步正在发生
有你的错误。 d3.json
和d3.tsv
都是异步调用,它们从Web加载文件。
创建一个数组,其中第一项是已解析的json,第二项是地图
不。呼叫返回承诺,而不是立即可用的结果,可以同步检查它们是否成功。您可能想刷新关于what a Promise
object represents的知识。