【问题标题】:Why do we use promises instead of if/then statements?为什么我们使用 Promise 而不是 if/then 语句?
【发布时间】:2019-06-27 15:23:11
【问题描述】:

我正在跟随 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/value 对的映射

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 数组。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    d3.json()d3.tsv()都是异步网络调用;当调用完成时,这些承诺将得到解决。您的伪代码不起作用,因为 if 会在异步调用进行后立即运行,而不是在它们完成后运行。

    Promises 是一种说法,即“做这件事需要一段时间,然后当它完成后,用它的结果做某事”。 (正如 cmets 所指出的,这是一个简化的定义,但可能足以开始使用。)同步版本将是“做这件事需要一段时间,然后立即尝试对结果做一些事情(即还没到)。”

    Promise.all(promises).then(ready);
    

    在这种情况下,您实际上将 Promise 包装在另一个 Promise 中——两个 d3 调用每个都是一个 Promise,然后 Promise.all() 将另一个 Promise 包装在它们周围,这将等到两个内部的 Promise 都完成在解雇其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
    

    【讨论】:

    • “Promise.all(promises) 将开始这两个异步调用”。不像我理解的那样。这些承诺已经开始 - Promise.all 只是等待他们解决或拒绝。
    • 啊,是的,我过于简单化了。我会扩展答案,你是对的。
    • "做这件事需要一段时间,然后当它完成后用它的结果做一些事情" - 听起来你在描述一般的异步回调,而不是特别的承诺.
    • @Bergi 对于这个答案,我认为这是最重要的部分,是的;对于这个级别的人来说,更详细的细节会比帮助更令人困惑。
    【解决方案2】:

    我没有想到任何异步正在发生

    这是你的错误。 d3.jsond3.tsv 都是异步调用,它们从网络加载文件。

    创建一个数组,其中第一项是解析的 json,第二项是地图

    没有。调用返回承诺,而不是立即可用并且可以同步检查其成功的结果。您可能想在what a Promise object represents 上更新您的知识。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-18
      • 2016-12-08
      • 1970-01-01
      • 2017-09-27
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多