0

基本上,我正在尝试建立一棵树,其中每个节点都有对其父节点的引用。我尝试了以下方法:

function insert_node(node_data, parent_id) {
  var deferral = Q.defer()
  deferral.promise.then(async_create_node(node_data, parent_id))

  deferral.promise.then(function(parent_node_id) {
    var deferral = Q.defer()
    node_data.children.forEach(function(node) {
      deferral.promise.then(insert_node(generate_node_data(node), parent_node_id))
    }
    return deferral.resolve();
  }

  return deferral.resolve();
}

function insert_all_nodes() {
  var deferral = Q.defer();
  deferral.promise.then(insert_node(top_node));
  deferral.resolve()
}

问题是我需要它一次只创建一个节点,然后等到该节点创建完成,然后才能继续下一个节点。它现在的工作方式是在第一个节点完成之前开始创建一个新节点,这会导致问题。我尝试过以多种方式嵌套函数,并使用 Q.fcall()。我需要为多个子节点返回的 id async_create_node,否则我只会使用递归。

4

1 回答 1

0

异步性和递归的结合使得这有点棘手。

首先,我们必须确保它async_create_node()返回了一个promise,否则就没有承认它的异步性的基础,整个企业都需要同步。

其次,假设在每一层(尤其是最顶层),我们不仅需要知道层的节点已经创建,还需要知道它下面的整个树已经创建。

然后,您应该能够执行以下操作:

function insert_node(node_data, parent_id) {
    var dfrd = Q.defer();
    async_create_node(node_data, parent_id).then(function(id) {
        var promises = [];
        node_data.children.forEach(function(node) {
            promises.push(insert_node(generate_node_data(node), id));
        });
        Q.all(promises).then(dfrd.resolve);
    });
    return dfrd.promise;
}

function insert_all_nodes() {
    return insert_node(top_node_data, top_node_id);
}

这都是我的想法,未经测试。

编辑

要顺序创建兄弟节点,您可以在循环中构建一个.then()链,forEach如下所示:

function insert_node(node_data, parent_id) {
    var dfrd = Q.defer();
    async_create_node(node_data, parent_id).then(function(id) {
        var p = Q.defer().resolve().promise;//Seed promise on which to build a then() chain.
        node_data.children.forEach(function(node) {
            p = p.then(function() {
                insert_node(generate_node_data(node), id);
            });
        });
        p.then(dfrd.resolve);
    });
    return dfrd.promise;
}
于 2013-06-16T07:42:13.350 回答