在初始承诺成功后拒绝内心的承诺?

Rejecting inner promise after initial promise has succeeded?

我有一个函数在产生一些数据之前发出两个异步请求。

方法的调用者不需要知道它的实现细节。来电者只需要:

由于可以在第一个 promise 完成后调用 abort,所以这很复杂。第二个请求已经在进行中,但调用者尚未收到数据。因此,调用者假设它可以调用中止,但拒绝第一个承诺将没有任何效果。

我通过以下方法解决了这个问题,但感觉很老套。我错过了什么吗?

var ajaxOptions = {
  url: 'https://www.googleapis.com/youtube/v3/search',
  data: {
    part: 'id',
    key: 'AIzaSyDBCJuq0aey3bL3K6C0l4mKzT_y8zy9Msw',
    q: 'Hello'
  }
};

function search(options) {
  var jqXHR = $.ajax(ajaxOptions);

  var innerJqXHR = null;
  jqXHR.then(function(data, statusText, jqXHR) {
    innerJqXHR = $.ajax(ajaxOptions);
    innerJqXHR.done(options.done);
    innerJqXHR.fail(options.fail);

    return innerJqXHR;
  }, options.fail);

  return {
    promise: jqXHR,
    innerPromise: innerJqXHR,
    fullAbort: function() {
      jqXHR.abort();

      if (innerJqXHR !== null) {
        innerJqXHR.abort();
      }
    }
  }
}

var searchReturn = search({
  done: function() {
    console.log('inner done');
  },
  fail: function() {
    console.log('inner or outer fail');
  }
});

searchReturn.fullAbort();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

由于您的代码看起来有点像伪代码(对我来说其中有未回答的问题),我能提供的最好的是一个想法的框架。一般的想法是你 return 从你的搜索函数中做两件事,一个只有当两个 ajax 调用都被解析时才被解析的承诺和一个可以被调用以中止过程的中止函数。

function search(options) {
    var activeAjax = $.ajax(args for first ajax call).then(function(data) {
        // second ajax call changes activeAjax so abort will work
        // on the active ajax call
        activeAjax = $.ajax(args for second ajax call).then(function(data) {
            activeAjax = null;
            // collect your final data here and return it
            // this will be the resolved value of the final promise
            return finalData;
        });
        return activeAjax;
    });

    return {
        promise: activeAjax,
        abort: function() {
            if (activeAjax) {
                activeAjax.abort();
            }
        }
    };
}

// usage:
var searchInProgress = search(...);
searchInProgress.promise.then(function(data) {
    // search finished successfully, answer is in data
}, function(err) {
    // either one of the promises failed
});

// and, at any time, you can call searchInProgress.abort();