简体   繁体   中英

How to recursively iterate over a tree structure of files to fetch using Promises?

I have a structure of files I want to load (all json). A file fetched will show whether it has children that also need to be fetched.

Currently I have this:

    storage.digestType = function (my_storage, my_type) {
      var type_list, blocker;

      type_list = [];
      blocker = new Promise(function (resolve) {

        function handler(my_pass_store, my_type_list, my_pending_parent) {
          return fetchDefinition(my_pass_store, my_type_list)
            .then(function (my_result_list) {
              var i, len, iter, kids, pending_list, pender;

              // kids blockers will go in here
              pending_list = [];

              for (i = 0, len = my_result_list.length; i < len; i += 1) {
                iter = my_result_list[i];
                kids = iter.child_portal_type_list;

                // update type_list
                type_list.push(iter.base_portal_type);

                // there are kids, so call handler on them
                if (kids) {
                  pender = new Promise(function (pending_resolve) {
                    handler(my_storage, kids, pending_resolve);
                  });
                  pending_list.push(pender);
                }

                return Promise.all(pending_list)
                  .then(function (response_list) {
                    my_pending_parent(type_list);
                  });
              }
            });
        }

        // start with first call
        return handler(my_storage, [my_type], resolve);
      });

      return blocker
        .then(function () {
          console.log("DONE DONE");
          console.log(type_list);
        });
    }

My file structure is n levels deep. I'm calling a method named fetchDefinition which will return something like this:

{
  "portal_type": "portal_type_definition",
  "base_portal_type": "portal_index",
  "child_portal_type_list": null
}

I'm adding base_portal_type to my type_list parameter (log) and then I'm checking on child_portal_type_list whether it's null or an array like ["foo", "bar"...] . In the latter case I'm passing the array to a new call of handler .

My problem is, I seem to be failing on the first time child_portal_type_list=null . This seems to resolve all pending blockers and I'm finishing to early.

Question :
How do I correctly set a blocking promise and pass it into recursive calls?

Thanks!

After sitting in front of this method for quite a while I realized I put the return statement inside my for-loop vs afterwards. This is the reason, the resolvers are triggered to early. Easy fix now... here is the correct code in case someone else needs something like this:

storage.digestType = function (my_storage, my_type) {
  var type_list, blocker;

  type_list = [];
  blocker = new Promise(function (resolve) {

    function handler(my_pass_store, my_type_list, my_pending_parent) {
      return fetchDefinition(my_pass_store, my_type_list)
        .then(function (my_result_list) {
          var i, len, iter, kids, pending_list, pender;

          // kids blockers will go in here
          pending_list = [];

          for (i = 0, len = my_result_list.length; i < len; i += 1) {
            iter = my_result_list[i];
            kids = iter.child_portal_type_list;

            // update type_list
            type_list.push(iter.base_portal_type);

            // there are kids, so call handler on them
            if (kids) {
              pender = new Promise(function (pending_resolve) {
                handler(my_storage, kids, pending_resolve);
              });
              pending_list.push(pender);
            }
          }

          // THE RETURN STATEMENT SHOULD BE OUTSIDE THE LOOP!
          return Promise.all(pending_list)
            .then(function (response_list) {
              my_pending_parent(type_list);
            });
        });
    }

    // start with first call
    return handler(my_storage, [my_type], resolve);
  });

  return blocker
    .then(function () {
      console.log("DONE DONE");
      console.log(type_list);
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM