Javascript 如何使用promise、.then()、.catch()多次尝试异步函数
我需要对异步函数Javascript 如何使用promise、.then()、.catch()多次尝试异步函数,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,我需要对异步函数getDBfileXHR进行多次尝试,但我不知道如何处理这个问题。我不太会把承诺连成链子。我应该像这样把它们拴起来吗 return getDBfileXHR(dbUrl(), serverAttempts) .then(function () { // success console.log('-basic XHR request succeeded.'); return dbReadyDeferred.promise; })
getDBfileXHR
进行多次尝试,但我不知道如何处理这个问题。我不太会把承诺连成链子。我应该像这样把它们拴起来吗
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function () { // success
console.log('-basic XHR request succeeded.');
return dbReadyDeferred.promise;
})
.catch(function (){
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function (){
console.log('-basic XHR request succeeded after second attempt.');
return dbReadyDeferred.promise;
})
.catch(function () { // error
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
});
})
或者像这样:
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function () { // success
console.log('-basic XHR request succeeded.');
return dbReadyDeferred.promise;
})
.catch(function (){
if (typeof serverAttempts !== "undefined") serverAttempts++;
console.log('on passe dans le catch, serverAttempts = ', serverAttempts)
if (serverAttempts < 2) {
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function () { // success
console.log('-basic XHR request succeeded.');
return dbReadyDeferred.promise;
})
.catch(function (){
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
})
} else {
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
}
})
返回getDBfileXHR(dbUrl(),servertruments)
.then(函数(){//success
log('-basic XHR请求成功');
返回dbreadyFerred.promise;
})
.catch(函数(){
如果(服务器尝试的类型!=“未定义”)服务器尝试++;
log('on passe dans le catch,serverAttempts=',serverAttempts)
如果(服务器尝试次数<2){
返回getDBfileXHR(dbUrl(),servertruments)
.then(函数(){//success
log('-basic XHR请求成功');
返回dbreadyFerred.promise;
})
.catch(函数(){
log(“-basic XHR请求失败,返回到本地数据库文件或本地存储数据库…”);
返回fallbackToLocalDBfileOrLocalStorageDB();
})
}否则{
log(“-basic XHR请求失败,返回到本地数据库文件或本地存储数据库…”);
返回fallbackToLocalDBfileOrLocalStorageDB();
}
})
第二个代码似乎有效,但我不确定它是否是最佳实践。一个简单而灵活的解决方案包括创建一个帮助器好处,可用于任何需要重试的承诺:
var retryP = (fn, retry) => fn(retry).catch(err => (!isNaN(retry) && retry > 0) ? retryP(fn, retry - 1) : Promise.reject(err));
此通用函数将重试fn
最多尝试次,超过1将重试一次,即进行两次尝试
然后可以编写您的函数:
var serverAttempts = 1;
// this is should be the retry attempts,
// so 0 is try at most once, 1 is at most twice etc
// argument n will be the number of retries "in hand",
// so it counts down from the passed in value to 0
return retryP(n => getDBfileXHR(dbUrl(), serverAttempts - n), serverAttempts)
.then(() => {
console.log('-basic XHR request succeeded after second attempt.');
return dbReadyDeferred.promise;
})
.catch(() => {
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
});
如果您对ES2015+语法不满意
助手:
代码:
可能重复的语法在这个问题中不相同,我不知道如何与我的案例联系起来。getDBfileXHR
是否真的需要servertruments参数,它是基于0还是基于1?不,它真的不需要它。。。。我的意思是,如果你能提出一些没有它的建议,我一点也不反对
var retryP = function retryP(fn, retry) {
return fn(retry).catch(function (err) {
return !isNaN(retry) && retry > 0 ? retryP(fn, retry - 1) : Promise.reject(err);
});
};
var serverAttempts = 1;
return retryP(function (n) {
return getDBfileXHR(dbUrl(), serverAttempts - n);
}, serverAttempts)
.then(function () {
console.log('-basic XHR request succeeded after second attempt.');
return dbReadyDeferred.promise;
})
.catch(function () {
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
});