【问题标题】:Abort ajax request in a promise在 Promise 中中止 ajax 请求
【发布时间】:2015-12-06 10:54:46
【问题描述】:

我正在构建一个表单验证并学习 Promise,我决定使用 Promise 模式实现异步验证功能:

var validateAjax = function(value) {
    return new Promise(function(resolve, reject) {
        $.ajax('data.json', {data: {value: value}}).success(function(data, status, xhr) {
            if (data.valid) {
                resolve(xhr)
            }
            else {
                reject(data.message)
            }
        }).error(function(xhr, textStatus) {
            reject(textStatus)
        })
    })
}

//...
var validators = [validateAjax];
$('body').delegate('.validate', 'keyup', function() {
    var value = $('#the-input').val();
    var results = validators.map(function(validator) {
        return validator(input)
    });

    var allResolved = Promise.all(results).then(function() {
        //...
    }).catch(function() {
        //...
    })
});

这似乎工作正常,输入被验证为用户类型(代码被简化为不会太长,例如 keyup 丢失后超时等等)。

现在我想知道如果前一个 keyup 事件的验证仍在进行中,如何终止 ajax 请求。是否有可能检测到承诺处于哪个状态并可能从外部拒绝承诺?

【问题讨论】:

    标签: javascript ajax promise cancellation


    【解决方案1】:

    Promise 取消目前在规范中,还没有内置的方法来做到这一点(虽然它即将推出)。我们可以自己实现:

    var validateAjax = function(value) {
        // remove explicit construction: http://stackoverflow.com/questions/23803743
        var xhr = $.ajax('data.json', {data: {value: value}}); 
        var promise = Promise.resolve(xhr).then(function(data){
             if(!data.isValid) throw new Error(data.message); // throw errors
             return data;
        });
        promise.abort = function(){
           xhr.abort();
        });
        return promise;
    }
    

    现在,我们可以通过在 promise 上调用 abort 来终止 validateAjax 调用:

    var p = validateAjax("..."); // make request
    p.abort(); // abort it;
    

    【讨论】:

    • 太好了,我明白了,谢谢你的回答。无论如何,关于删除显式构造 - xhr 仍然需要从 validateAjax 函数返回,对吧?
    • 您的 validateAjax 返回 undefined - 是否缺少一行?
    • @LukasKral - 我认为需要返回 var promise,因为它具有 .abort 函数 - 但我没有编写代码,所以我只能推测
    • 这是个好主意。不幸的是,该功能将在链中丢失。所以 var p = validateAjax(...).then(..); p.abort(); // 没有这个函数
    • 对,它没有链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 2018-05-28
    • 2017-10-30
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多