Отклонение / разрешение обещания извне его тела

#ember.js #promise #cancellation

#ember.js #обещание #отмена

Вопрос:

Мне нужно отклонить обещание извне его тела, чтобы обработать случай пользователя, который хотел отменить действие.

Здесь мне нужно запустить несколько загрузок одновременно, вызывая #start при каждой загрузке в очередь. Класс, который управляет очередью загрузок, затем сохраняет все обещания и использует Ember.RSVP.all для обработки, когда все обещания разрешены или одно отклонено. Это работает нормально.

Теперь я хотел бы отменить загрузку

 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 */)
  }
});
  

Я думал о многих способах справиться с этим, но я не нашел ни одного подобного метода myPromise.reject(reason) .

Итак, что я сделал, это сохранить reject функцию в Upload экземпляре и вызвать ее из моего cancel метода, вот так :

 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 */)
  }
});
  

Для меня это звучит немного грязно, и я хотел бы знать, есть ли лучший способ сделать это.

Спасибо за ваше время!

Комментарии:

1. Почему вы обертываете startUpload с помощью конструктора promise?

2. Подождите, нет — это логически неверно (то, что вы здесь делаете), вы рассчитываете на то, что обещания разрешаются только один раз, чтобы предотвратить побочные эффекты, а не фактически отменить загрузку. Я рекомендую вам использовать библиотеку обещаний, которая поддерживает отмену, такую как Bluebird.

Ответ №1:

 var deferred = Ember.RSVP.defer();

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

Для доступа к обещанию (для уточнения и т. Д.)

 deferred.promise.then(function(){
  console.log('all good');
},function(){
  console.log('all bad');
});
  

Комментарии:

1. Извините за время, потраченное на ответ, и спасибо за ваше предложение. Я приму его, как только протестирую его в понедельник!