【问题标题】:Wait for nested sub-promises等待嵌套的子承诺
【发布时间】:2018-05-07 19:27:10
【问题描述】:

我正在尝试为 Web 应用程序 API 实现前端。 需要进行三个 Ajax 调用。

  1. 列出所有组。
  2. 为每个组列出其成员。
  3. 从每个组的成员中获取terminals 并扩展值。

三个 Ajax 调用如下所示:

  function getGroups () {
    return jQuery.ajax({
      url: "https://webapp.mydomain.com/group?session=" + his.getSessionToken() + "&customer=test"
    });
  }

  function getMembers (group) {
    return jQuery.ajax({
      url: "https://webapp.mydomain.com/group/" + group.id + "/member?session=" + his.getSessionToken() + "&customer=test"
    });
  }

  function getTerminal (terminal) {
    return jQuery.ajax({
      url: "https://webapp.mydomain.com/terminal/" + terminal.tid + "?session=" + his.getSessionToken() + "&customer=test"
    });
  }

我还有以下杂项功能:

  function display (html) {
    document.getElementById('result').innerHTML = html;
  }

  function success (message) {
    display('Success: ' + JSON.stringify(message, null, 2));
  }

  function error (error) {
    display('Error: ' + JSON.stringify(error, null, 2));
  }

现在我面临如何正确链接各个 Promise(实际上是 Deferreds)的问题。

我尝试了以下方法:

  function setTerminal (terminals, index) {
    function curry (terminal) {
      terminals[i] = terminal;
    }

    return curry;
  }

  function expandMembers (members) {
    var promises = [];
    var promise;
    var terminals = members.terminal || [];

    for (var i = 0; i < terminals.length; i++) {
      promise = getTerminal(terminals[i]);
      promise.then(setTerminal(terminals, i));
      promises.push(promise);
    }

    return Promise.all(promises);
  }

  function getMembers (groups) {
    var promises = [];
    var promise;

    for (var i = 0; i < groups.length; i++) {
      console.log('Group #' + i + ': ' + JSON.stringify(groups[i]));
      promise = getMembers(groups[i]);
      promise.then(expandMembers);
      promises.push(promise);
    }

    return Promise.all(promises);
  }

  function listGroups (groups) {
    getGroups().then(getMembers).then(success);
  }

然而,这不会等待子承诺(实际上返回一个空列表列表,每个组一个)。

我想要实现的是:

  1. 获取所有组 (getGroups)。
  2. 为每个组获取所有成员 (getMembers)。
  3. 在组对象上设置成员。
  4. 对于组成员中的每个终端,获取详细的终端信息 (getTerminal)。
  5. 用详细的终端信息替换简短的终端信息。
  6. 如果上述所有操作都完成,则显示组 JSON 列表。

我很茫然。

【问题讨论】:

  • 至于解决方案。我不是 JavaScript 中的 Promise 专家(甚至到目前为止),但根据其他语言中类似结构的经验,我认为子 Promise 应该 await the result of the promises they rely on,并且您返回的唯一 Promise 是顶级 Promise。该承诺只有在所有子承诺都完成后才会完成/履行,因为它正在等待它们。等待也应该在后台发生,所以你的主脚本不会被它阻塞,除非你也决定等待主脚本。

标签: javascript ajax promise


【解决方案1】:

then() 返回一个新的 Promise,它在传递的函数返回时解析。所以如果我正确理解了你的问题,这就是你可能想要做的:

for (var i = 0; i < terminals.length; i++) {
  promise = getTerminal(terminals[i]);
  promises.push(promise.then(setTerminal(terminals, i)));
}

return Promise.all(promises);

(适用于所有 Promise 组)

【讨论】:

  • 是的。这解决了我的问题。此外,我使用 groups 变量初始化了 promises 数组,因此结果数组的第一个值将是组数组。
猜你喜欢
  • 2020-04-21
  • 2018-05-05
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
  • 2019-05-29
  • 2017-04-02
  • 2013-09-16
相关资源
最近更新 更多