[英]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
有多个后续操作。
但是,我不得不重复always
和fail
代码。 如何让它们更干燥,以便它们只写一次,但在两种情况下都使用(如果需要,还可以使用其他示例)。 因此,我不能只将时间移动到方法中并传递回调,因为可能存在多个并且在不同的情况下。 所以这不起作用:
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()。 没有法律规定always
或fail
必须在链条中排在最后。
这是一个解决方案的草图,我没有测试过。
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.