Skip to content

Queueing up multiple promises without waiting on last promise result #366

Open
@jasonayre

Description

@jasonayre

Hi,

I have some code that I thought was working, but realized it was not when I ran multiple server processes, and saw that the requests I was making were dependent on the previous requests to complete. - I can see that the promises are being generated since they are visible in the scope.$pending count, but for some reason, it's not queueing up the actual network request. For example (just going to post the before and after in its entirety):

import _ from 'lodash';

export default /* @ngInject */ function(restmod, $http, RMPackerCache, $q, ProgressBar) {
  return restmod.mixin({
    $extend: {
      Collection: {
        $withBatchesOf(batch_size=25) {
          let batch_collection = this.$type.$collection();
          batch_collection.original_collection = this;
          batch_collection.batches = _.chunk(batch_collection.original_collection, batch_size);
          batch_collection.progress = new ProgressBar(0, batch_collection.batches.length);
          return batch_collection;
        },
        $createAllBatches() {
          let self = this,
              model = this.$type,
              collection_key = model.getProperty('plural'),
              request_url = model.$collectionPath('create_all'),
              batch_promises,
              batch_records,
              request_data,
              request;

          batch_promises = _.map(self.batches, function(batch){
            return self.$action(function(){
              batch_records = _.map(batch, function(record){
                return record.$encode();
              });

              request_data = {};
              request_data[collection_key] = batch_records;

              request = {
                url: request_url,
                method: 'POST',
                data: request_data
              };

              self.$dispatch('before-create-batch', [request]);

              return self.$send(request, function(_response){
                RMPackerCache.prepare();

                var raw = model.unpack(this, _response.data), pk, records;

                self.$decode(raw);
                self.progress.tick();
                self.$dispatch('after-create-batch', []);

                RMPackerCache.clear();
              }).$asPromise();
            });
          });

          return batch_promises;
        }
      }
    }
  })
}

The self.$action and self.$send are where I'm confused. I've tried a combination of doing it with/without one or the other, and with/without explicitly calling $asPromise at the end, but haven't gotten it to work. But from digging around the docs it seems like this is the way I am supposed to do this? The code I have now for comparison (which works but breaks the hook apis/I then don't have access to the collection $pending and $hasPendingActions which other code relies upon), is:

import _ from 'lodash';

export default /* @ngInject */ function(restmod, $http, RMPackerCache, $q, ProgressBar) {
  return restmod.mixin({
    $extend: {
      Collection: {
        $withBatchesOf(batch_size=25) {
          let batch_collection = this.$type.$collection();
          batch_collection.original_collection = this;
          batch_collection.batches = _.chunk(batch_collection.original_collection, batch_size);
          batch_collection.progress = new ProgressBar(0, batch_collection.batches.length);
          return batch_collection;
        },
        $createAllBatches() {
          let self = this,
              model = this.$type,
              collection_key = model.getProperty('plural'),
              request_url = model.$collectionPath('create_all'),
              batch_promises,
              batch_records,
              request_data,
              request;

          batch_promises = _.map(self.batches, function(batch){
            batch_records = _.map(batch, function(record){
              return record.$encode();
            });

            request_data = {};
            request_data[collection_key] = batch_records;

            request = {
              url: request_url,
              method: 'POST',
              data: request_data
            };

            self.$dispatch('before-create-batch', [request]);

            return $http(request).then(function(response){
              RMPackerCache.prepare();

              var raw = model.unpack(self, response.data);

              self.$decode(raw);
              self.progress.tick();
              self.$dispatch('after-create-batch', []);

              RMPackerCache.clear();
            });
          });

          return batch_promises;
        }
      }
    }
  })
}

Which works, but now api's are broken. Can you tell me if I'm doing something obviously stupid and or where I'm going wrong, or if angular-restmod is working as expected in this instance? (Like are collections only supposed to have one active promise going on at the same time?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions