最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

承诺和递归

IT培训 admin 6浏览 0评论

承诺和递归

情况就是这样。我继承了一个难以使用的数据库模式(我们以前都曾在那里工作过),而Node现在更加突出了这一点。我需要做的是递归地遍历记录的关系(大多数时间是one2many)并且当记录的对象等于数组常量中的一个集合时停止,但仅针对那个关系链。所有其他关系都需要继续,直到它们达到同一点。每个部署的关系数量可能不同,因此无法创建静态解决方案。

gatherDataToSync: async (connection, recordId) => {
    self.recordIdsUsed.push(recordId);

    let objectId = await referenceHelper.getObjectIdForRecordId(connection, recordId);
    let objectData = await self.getRelatedObjectsInformation(connection, recordId);

    self.objectCollection.push({
        "recordId": recordId,
        "objectId": objectId,
        objectData
    });

    if (referenceHelper.includes(self.objectListToStopExecutionAt, objectId) === false) {
        let relationships = objectData['relationships'];

        if (relationships != null) {
            for (let i = 0; i < relationships.length; i++) {

                if (referenceHelper.includes(self.relationshipsToIgnore, relationships[i]['id']) === false) {
                    let relationshipRecordIds = relationships[i]['relationships'];

                    if (relationshipRecordIds != null) {
                        for (let j = 0; j < relationshipRecordIds.length; j++) {
                            if (referenceHelper.includes(self.recordIdsUsed, relationshipRecordIds[j]) === false) {
                                await self.gatherDataToSync(connection, relationshipRecordIds[j]);
                            }
                        }
                    }
                }
            }
        }
    }
},

这是我的递归方法。我需要让循环中的所有awaits在原始调用gatherDataToSync函数之前完成处理,以将其promise返回给它调用的函数。有没有办法做到这一点,还是我没有考虑到这一点?

self.recordIdsUsedself.objectCollection都是模块变量,用于跟踪数据,以便在循环中不会出于比较目的而不同步。

如果您需要更多代码,请告诉我,因为我不确定需要什么才能了解​​正在发生的事情。

预先感谢您的帮助!

回答如下:

我不确定以下代码是否适合您(取决于您如何改变值以及如何基于变异值实现referenceHelper.includes)。问题是你必须返回一些东西,以便gatherDataToSync的调用者知道它什么时候完成。

您的代码不会返回任何内容,但如果它返回await self.gatherDataToSync,它将以最慢的方式执行,因为它正在堆叠所有异步处理。

    gatherDataToSync: async (connection, recordId) => {
      self.recordIdsUsed.push(recordId);
      //minor improvement maybe, you can do these 2 things in parallel
      let [objectId,objectData] = await Promise.all(
        referenceHelper.getObjectIdForRecordId(connection, recordId),
        self.getRelatedObjectsInformation(connection, recordId)
      );

      self.objectCollection.push({
          "recordId": recordId,
          "objectId": objectId,
          objectData
      });

      if (referenceHelper.includes(self.objectListToStopExecutionAt, objectId) === false) {
          //you return a recursive promise here so you can await calling gatherDataToSync
          return Promise.all(
            //no need for if statement and for loop, just take out all items you don't need
            (objectData['relationships'] || [])//no need for if null
            .filter(//filter out the ones you don't need
              item =>
                referenceHelper.includes(self.relationshipsToIgnore, item) !== false
            )
            .map(
              item => 
                (item['relationships'] || [])//no need for inner if null
                .filter(//filter out the ones you don't need
                  item =>
                    referenceHelper.includes(self.recordIdsUsed, item) !== false
                )
            )
            .map(
              item =>//this is an array of array of objectIds
                Promise.all(//create a promise with recursive promises
                  item.map(
                    item=>self.gatherDataToSync(connection, item)
                  )
                )
            )
        );
      }
    }

承诺和递归

情况就是这样。我继承了一个难以使用的数据库模式(我们以前都曾在那里工作过),而Node现在更加突出了这一点。我需要做的是递归地遍历记录的关系(大多数时间是one2many)并且当记录的对象等于数组常量中的一个集合时停止,但仅针对那个关系链。所有其他关系都需要继续,直到它们达到同一点。每个部署的关系数量可能不同,因此无法创建静态解决方案。

gatherDataToSync: async (connection, recordId) => {
    self.recordIdsUsed.push(recordId);

    let objectId = await referenceHelper.getObjectIdForRecordId(connection, recordId);
    let objectData = await self.getRelatedObjectsInformation(connection, recordId);

    self.objectCollection.push({
        "recordId": recordId,
        "objectId": objectId,
        objectData
    });

    if (referenceHelper.includes(self.objectListToStopExecutionAt, objectId) === false) {
        let relationships = objectData['relationships'];

        if (relationships != null) {
            for (let i = 0; i < relationships.length; i++) {

                if (referenceHelper.includes(self.relationshipsToIgnore, relationships[i]['id']) === false) {
                    let relationshipRecordIds = relationships[i]['relationships'];

                    if (relationshipRecordIds != null) {
                        for (let j = 0; j < relationshipRecordIds.length; j++) {
                            if (referenceHelper.includes(self.recordIdsUsed, relationshipRecordIds[j]) === false) {
                                await self.gatherDataToSync(connection, relationshipRecordIds[j]);
                            }
                        }
                    }
                }
            }
        }
    }
},

这是我的递归方法。我需要让循环中的所有awaits在原始调用gatherDataToSync函数之前完成处理,以将其promise返回给它调用的函数。有没有办法做到这一点,还是我没有考虑到这一点?

self.recordIdsUsedself.objectCollection都是模块变量,用于跟踪数据,以便在循环中不会出于比较目的而不同步。

如果您需要更多代码,请告诉我,因为我不确定需要什么才能了解​​正在发生的事情。

预先感谢您的帮助!

回答如下:

我不确定以下代码是否适合您(取决于您如何改变值以及如何基于变异值实现referenceHelper.includes)。问题是你必须返回一些东西,以便gatherDataToSync的调用者知道它什么时候完成。

您的代码不会返回任何内容,但如果它返回await self.gatherDataToSync,它将以最慢的方式执行,因为它正在堆叠所有异步处理。

    gatherDataToSync: async (connection, recordId) => {
      self.recordIdsUsed.push(recordId);
      //minor improvement maybe, you can do these 2 things in parallel
      let [objectId,objectData] = await Promise.all(
        referenceHelper.getObjectIdForRecordId(connection, recordId),
        self.getRelatedObjectsInformation(connection, recordId)
      );

      self.objectCollection.push({
          "recordId": recordId,
          "objectId": objectId,
          objectData
      });

      if (referenceHelper.includes(self.objectListToStopExecutionAt, objectId) === false) {
          //you return a recursive promise here so you can await calling gatherDataToSync
          return Promise.all(
            //no need for if statement and for loop, just take out all items you don't need
            (objectData['relationships'] || [])//no need for if null
            .filter(//filter out the ones you don't need
              item =>
                referenceHelper.includes(self.relationshipsToIgnore, item) !== false
            )
            .map(
              item => 
                (item['relationships'] || [])//no need for inner if null
                .filter(//filter out the ones you don't need
                  item =>
                    referenceHelper.includes(self.recordIdsUsed, item) !== false
                )
            )
            .map(
              item =>//this is an array of array of objectIds
                Promise.all(//create a promise with recursive promises
                  item.map(
                    item=>self.gatherDataToSync(connection, item)
                  )
                )
            )
        );
      }
    }

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论