我正在构建表单验证并学习promises我决定使用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请求.是否可能以某种方式检测承诺在哪种状态并且可能拒绝来自外部的承诺?
解决方法
Promise取消目前正在规范中,目前还没有内置的方法(它即将推出).我们可以自己实现它:
- var validateAjax = function(value) {
- // remove explicit construction: https://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;