在 JavaScript 中,当 `parent()` returns 一个 Promise 时,如何实现一个递归的 `ancestors()` 函数

In JavaScript, how to implement a recursive `ancestors()` function when `parent()` returns a Promise

假设我在 thing.js 中有以下内容:

var db = require('my-database-module');

module.exports = class Thing() {
  constructor(id, parentId, name) {
    this.id = id;
    this.parentId = parentId;
    this.name = name;
  }

  static find(id) {
    // NOTE: The following find() function returns a Promise.
    return db.collection('things').find(id);
  }

  parent() {
    return this.constructor.find(this.parentId);
  }
}

通常情况下,查找事物将通过以下方式完成:

var Thing = require('thing');

Thing.find(123).then(function(thing) {
  // Do something with `thing`
});

您会注意到我想要实现一个 parent/child 层次结构。我想添加一个 ancestors 函数,该函数 returns 一个祖先数组 Thing objects 对于 Thing:

的给定实例
module.exports = class Thing() {

  // ...

  ancestors() {
    var a = []

    // Can't figure this out...

    return a;
  }
}

因为 Thing#parent 函数 returns 是一个 Promise,所以我对 ancestors 函数应该如何工作感到困惑。它需要递归查找 Thing 实例的连续 parents。

I've seen Array.prototype.reduce 函数可用于链接 Promise,但我不知道要预先链接的 Promise,因为它需要递归查找 parent,grand parent、曾祖父parent、等等

关于如何构造这个函数有什么想法吗?

如果方法 .parent() returns 一个满足价值的 promise 将是父级并且它 returns null 当没有更多的父级时,那么你可以写像这样:

ancestors() {
    var parents = [];

    function getNext(obj) {
        return obj.parent().then(function(parent) {
            if (!parent) {
                // if no more parents, then we must be done with the chain
                // so return the whole parent chain
                return parents;
            } else {
                // still got another parent, add to the array and keep going
                parents.push(parent);
                // returning another promise here chains it to the previous one
                return getNext(parent);
            }
        });
    }

    return getNext(this);
}

// usage
obj.ancestors().then(function(parents) {
    // access to the whole parents array here
});