繁体   English   中英

干然后和永远在jQuery承诺

[英]DRY Then and Always in jQuery Promise

我有以下示例JS代码:

function loadData(url, data) {
    return $.get(url, data ? data : {});
}

function example1() {

    showSpinner();

    $.when(loadData('/example1', { hello: 'world' }))
        .then(function (resp) {
            // do something with the data
        })
        .always(function(){
            hideSpinner();
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            handleError(jqXHR);
        });
}

function example2() {

    showSpinner();

    $.when(loadData('/example2', { hello: 'world' }))
        .then(function (resp) {
            // do something with the data
        })
        .then(function () {
            // do something else
        })
        .always(function(){
            hideSpinner();
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            handleError(jqXHR);
        });
}

example1()example2()使用相同的promise逻辑,并且会对返回的数据执行不同的操作,然后始终隐藏微调器并处理相同的失败(如果有的话)。 问题是我可能希望在每个示例中加载数据后执行不同的操作, then's有多个后续操作。

但是,我不得不重复alwaysfail代码。 如何让它们更干燥,以便它们只写一次,但在两种情况下都使用(如果需要,还可以使用其他示例)。 因此,我不能只将时间移动到方法中并传递回调,因为可能存在多个并且在不同的情况下。 所以这不起作用:

function customPromise(load, callback) {

    showSpinner();

    $.when(load)
    .then(function (resp) {
        callback(resp);
    })
    .always(function(){
        hideSpinner();
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
        handleError(jqXHR);
    });

}

function example3() {
    customPromise(loadData('/example2', { hello: 'world' }));
}

也许你可以.when()分解为一个返回一个promise本身的函数,然后调用它并用.then()链接到返回的promise,所以像foobar()。then()。then()。 没有法律规定alwaysfail必须在链条中排在最后。

这是一个解决方案的草图,我没有测试过。

function loadData(url, data) {
    return $.get(url, data ? data : {});
}

function wrapWhen(endpoint, data) {

    // return a promise
    return $.when(loadData(endpoint, data))
        .always(function(){
            hideSpinner();
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            handleError(jqXHR);
        });
}

function example1() {

    showSpinner();

    wrapWhen('/example1', {hello: 'world'})
        .then(function (resp) {
            // do something with the data
        });
}

function example2() {

    showSpinner();

    wrapWhen('/example2', {hello: 'world'})
        .then(function (resp) {
            // do something with the data
        })
        .then(function () {
            // do something else
        });
}

如果你有连续和未知数量的回调,我建议你将整个处理移动到创建的函数:

function handleRequest(url, data, errorCallback) {
    // create promise
    let promise = $.get(url, data ? data : {});

    // if callback functions provided as args, chain them in `then()` calls
    if (arguments.length > 3) {
        let callbacks = Array.slice.call(arguments, 3);
        let fn = (results) => (results);
        let callback;
        for (let i = 0; i < callbacks.length; i++) {
            callback = callbacks[i] instanceof Function ? callbacks[i] : fn;
            promise.then(callback);
        }
    }

    // handle static behavior
    promise.always(() => {
        hideSpinner();
    })
    .fail(errorCallback);

    // return the created promise
    return promise;
}

您现在可以使用此功能,如下所示:

handleRequest(
    '/example',
    {},
    (jqXHR, textStatus, errorThrown) => {
        handleError(jqXHR);
    },
    (resp) => {
        // do something with the data
    },
    () => {
        // do something else
    }
);

我能想到这样的事情。 不确定loadData是否应该负责显示微调器。

 $(function() { example1(); example2(); }); function loadData(url, data) { showSpinner(); return $.get(url, data ? data : {}) .always(function() { hideSpinner(); }) .fail(function(jqXHR, textStatus, errorThrown) { handleError(jqXHR); }); } function example1() { $.when(loadData('https://jsonplaceholder.typicode.com/users', { hello: 'world' })) .then(function(resp) { console.log(resp.length + ' lengthed data received'); }); } function example2() { $.when(loadData('https://jsonplaceholder.typicode.com/posts', { hello: 'world' })) .then(function(resp) { return resp; }) .then(function(data) { console.log(data.length + ' lengthed data received'); }); } function showSpinner() { console.log('Showing spinner...'); } function hideSpinner() { console.log('Hiding spinner...'); } function handleError(xhr) { console.error(xhr); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM