Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rejecting / Resolving a promise from outside its body

I have a need to reject a promise from outside its body, to handle the case of the user that wanted to cancel the action.

Here, I need to start several uploads at the same time, by calling #start on every queued uploads. The class that manages the uploads queue then stores all the promises and uses Ember.RSVP.all to handle when all the promises have resolved or one has rejected. This works fine.

Now, I would like to cancel the upload

App.Upload = Ember.Object.extend({
  start: function() {
    var self = this;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      self.startUpload() // Async upload with jQuery
        .then(
          function(resp) { resolve(resp) },
          function(error) { reject(error) }
        );
    });
  },

  cancel: function() {
    this.get('currentUpload').cancel() // Works, and cancels the upload
    // Would like to reject the promise here
  },

  startUpload: function() {
    return this.set('currentUpload', /* some jqXHR that i build to upload */)
  }
});

I have thought of many ways to handle it, but I don't found any method like myPromise.reject(reason).

So what I did, is to store the reject function in the Upload instance and call it from my cancel method, like this :

App.Upload = Ember.Object.extend({
  start: function() {
    var self = this;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      /* Store it here */
      self.set('rejectUpload', reject); 
      /* ------------- */

      self.startUpload() // Async upload with jQuery
        .then(
          function(resp) { resolve(resp) },
          function(error) { reject(error) }
        );
    });
  },

  cancel: function() {
    this.get('currentUpload').cancel() // Works, and cancels the upload

    /* Reject the promise here */
    var reject;
    if (reject = this.get('rejectUpload')) reject();
    /* ----------------------- */
  },

  startUpload: function() {
    return this.set('currentUpload', /* some jqXHR that i build to upload */)
  }
});

This sound a bit dirty to me, and I'd like to know if there was a better way to make this.

Thanks for your time !

like image 413
Vala Avatar asked Jun 19 '14 17:06

Vala


1 Answers

var deferred = Ember.RSVP.defer();

deferred.resolve("Success!");
deferred.reject("End of the world");

To access the promise (for thening etc)

deferred.promise.then(function(){
  console.log('all good');
},function(){
  console.log('all bad');
});
like image 155
Kingpin2k Avatar answered Nov 15 '22 10:11

Kingpin2k