在初步承诺成功后拒绝内心承诺? [英] Rejecting inner promise after initial promise has succeeded?
问题描述
我有一个函数在产生一些数据之前发出两个异步请求。
I have a function which issues two async requests before yielding some data.
该方法的调用者不需要知道其实现细节。所有来电者的需求是:
The caller of the method does not need to know about its implementation details. All the caller needs is:
- 第二次请求返回的数据。
- 能力调用abort而不是返回数据。
由于在第一个承诺完成后可以调用abort,这很复杂。第二个请求已在进行中,但调用者尚未接收数据。因此,调用者假设它可以调用abort,但是拒绝第一个promise将没有任何效果。
This is complicated by the fact that abort can be called after the first promise is done. The second request is already in-flight, but the caller has yet to receive data. So, the caller assumes it can call abort, but rejecting the first promise will have no effect.
我使用以下方法解决了这个问题,但感觉非常hacky。我错过了什么吗?
I work around this issue with the following, but it feels pretty hacky. Am I missing something?
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>
推荐答案
由于您的代码看起来有点像伪代码(对我来说是未解答的问题),我能提供的最好的是一个想法的框架。一般的想法是你从搜索函数中返回两个东西,一个只在解析了两个ajax调用时解析的promise和一个可以调用以中止该过程的中止函数。
Since your code looks a little like pseudo-code (unanswered questions in it for me), the best I can offer is a framework of an idea. The general idea is that you return two things from your search function, a promise that is resolved only when both ajax calls are resolved and an abort function that can be called to abort the process.
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();
这篇关于在初步承诺成功后拒绝内心承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!