我有一个函数,它在生成一些数据之前发出两个异步请求。
该方法的调用者不需要了解其实现细节。调用者的所有需求是:
- 第二个请求返回的数据。
- 能够调用中止而不返回数据。
由于在第一个 Promise 完成后可以调用 abort,这一事实使情况变得复杂。第二个请求已在进行中,但调用者尚未收到数据。因此,调用者假设它可以调用 abort,但拒绝第一个 promise 将不会产生任何效果。
我通过以下方法解决了这个问题,但感觉很hacky。我错过了什么吗?
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;以及一个可以调用以中止进程的中止函数。
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();
关于javascript - 最初的 promise 成功后又拒绝内心的 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28401679/