通过Promise Chain传递数据(angularjs)

时间:2018-05-02 15:48:27

标签: javascript angularjs promise angular-promise angularjs-http

这个问题很难描述,所以让我发一个例子。 上下文是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 个答案:

答案 0 :(得分:3)

在不同的抽象层次上发生事情时,不了解promiseA是完全有道理的。 doSomeAction抽象出http调用并提供任何取消底层http调用的API,打破抽象并揭示doSomeAction的实现细节。相反,我会考虑使doSomeAction可取消,即在它返回的对象上提供cancel方法。这种取消方法可以取消底层的http请求(如果有多个则取消其中几个)或者如果没有发出http请求则跳过取消,数据来自本地存储或对doSomeAction做任何有意义的事情,而不仅仅是特定的http请求只是该图层中更大图片的一部分。