这个问题很难描述,所以让我发一个例子 . 上下文是AngularJS $q
,但也欢迎任何基于ES6 Promise
的解决方案 .
假设我们要取消 $http
请求 . 在AngularJS中,这是通过提供承诺A到 $http.get()
方法来实现的 . 解决承诺A将导致取消请求 . 所以代码看起来像这样:
function httpCall() {
const promiseA = $q.defer();
const promiseB = $http.get(url, { timeout: promiseA.promise });
return promiseB;
}
为了返回 promiseA
以便 httpCall
的调用者可以取消请求,我找到的唯一方法是将其分配给 promiseB
,如下所示:
function httpCall() {
const promiseA = $q.defer();
let promiseB = $http.get(url, { timeout: promiseA });
promiseB.canceller = promiseA;
return promiseB;
}
问题是, promiseB
可以通过一个长的承诺链(例如动作调度,映射,其他后处理)传递,例如:
function doSomeAction() {
return httpCall()
.then((response) => {
processResponse(response);
return response;
});
}
显然, doSomeAction
的返回值与原始承诺 promiseB
的承诺不同 .
因此,如果我有一个调用 doSomeAction()
的函数,则此函数将无法检索 promiseB
(它只能获得 doSomeAction()
的返回承诺),因此无法取消请求 .
有人可能会说我们可以通过链传递数据( promiseA
) . 但是我认为 promiseA
的存在应该对链本身是透明的,即链中的函数永远不应该知道 promiseA
的存在 . 因此,我不能依赖链为我传递数据 .
欢迎任何建议 .
1 回答
不知道
promiseA
总是有意义,因为事情发生在不同的抽象层次上 .doSomeAction
抽象出http调用并提供任何取消底层http调用的API,打破抽象并揭示doSomeAction
的实现细节 . 相反,我会考虑使doSomeAction
可取消,即在它返回的对象上提供cancel
方法 . 这种取消方法可以取消底层的http请求(如果有多个则取消其中几个)或者如果没有发出http请求则跳过取消,数据是从本地存储获取的,或者对doSomeAction
执行任何有意义的操作,而不仅仅是特定的http请求这层的更大图片的一部分 .