为承诺链定义后备捕获?
Define fallback catch for promise chain?
我正在开发一个到处都使用 what-wg fetch 的应用程序。我们以这种方式定义了默认的获取中间件和选项:
export function fetchMiddleware(response) {
return new Promise(resolve => {
resolve(checkStatus(response));
}).then(parseJSON);
}
export const fetchDefaults = {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
我们以这种方式使用默认的中间件/获取选项:
fetch('/api/specific/route', fetchDefaults)
.then(fetchMiddleware)
.then(function(data) {
// ... Dispatch case-specific fetch outcome
dispatch(specificRouteResponseReceived(data));
});
我们想为整个应用程序中的所有 fetch
用法 添加一个通用的后备捕获,换句话说,像这样:
export function fetchGenericCatch(function(error) {
showGenericErrorFlashMessage();
})
fetch('/en/api/user/me/preferences', fetchDefaults)
.then(fetchMiddleware)
.then(function(data) {
dispatch(userPreferencesReceived(data));
})
.catch(fetchGenericCatch);
大量代码重复。我们想要一个效用函数 / class 可以为我们完成所有这些,例如像这样工作的东西:
genericFetch('/api/specific/route') // bakes in fetchDefaults and fetchMiddleware and fetchGenericCatch
.then(function(data) {
dispatch(userPreferencesReceived(data));
}); // gets generic failure handler for free
genericFetch('/api/specific/route') // bakes in fetchDefaults and fetchMiddleware and fetchGenericCatch
.then(function(data) {
dispatch(userPreferencesReceived(data));
})
.catch(function(error) {
// ...
}); // short-circuits generic error handler with case-specific error handler
主要警告是通用 catch
必须链接 在 特定案例 then
s / catch
es 之后。
关于如何使用 whatwg-fetch / ES6 Promises 实现这一点的任何提示?
相关:
有类似的帖子,但它们似乎没有解决在所有非默认 then
s 和 catch
es 之后运行 的默认捕获的需要:
编辑 10 月 14 日:
可能重复:Promises and generic .catch() statements
我认为解决方案很简单:
export function genericFetch(url, promise, optionOverrides) {
const fetchOptions = {...fetchDefaults, ...optionOverrides};
return fetch(url, fetchOptions)
.then(fetchMiddleware)
.then(promise)
.catch(function(error) {
showGenericFlashMessage();
});
}
不需要特殊错误处理程序的用例可以简单地这样使用:
genericFetch('/api/url', function(data) {
dispatch(apiResponseReceived(data));
});
需要特殊捕获或更复杂链的用例可以传递完整的承诺:
genericFetch('/api/url', function(response) {
return new Promise(resolve, reject => {
dispatch(apiResponseReceived(data));
}).catch(nonGenericCaseSpecificCatch); // short-circuits default catch
});
只要错误处理程序是 DRY,拥有 WET 代码并不是最糟糕的选择。
fetch(...)
...
.catch(importedFetchHandler);
它不会导致任何问题,并且符合 Bluebird 和 V8 承诺的行为,其中存在未处理的拒绝事件以确保没有未捕获的承诺。
实现这一点的最简单方法是为 fetch
promise:
引入类似 promise 的包装器
function CatchyPromiseLike(originalPromise) {
this._promise = originalPromise;
this._catchyPromise = Promise.resolve()
.then(() => this._promise)
.catch((err) => {
console.error('caught', err);
});
// every method but 'constructor' from Promise.prototype
const methods = ['then', 'catch'];
for (const method of methods) {
this[method] = function (...args) {
this._promise = this._promise[method](...args);
return this;
}
}
}
可以像
一样使用
function catchyFetch(...args) {
return new CatchyPromiseLike(fetch(...args));
}
像这样的承诺有其天然的局限性。
如果转换为真正的承诺,副作用将被丢弃:
Promise.resolve(catchyFetch(...)).then(() => /* won't be caught */);
而且它不能很好地与异步链一起使用(这是对所有承诺的禁忌):
var promise = catchyFetch(...);
setTimeout(() => {
promise.then(() => /* won't be caught */);
});
Bluebird 是一个不错的选择,无需在那里发明轮子,功能就是它的优点。 Local rejection events 看起来正是需要的东西:
// An important part here,
// only the promises used by catchyFetch should be affected
const CatchyPromise = Bluebird.getNewLibraryCopy();
CatchyPromise.onPossiblyUnhandledRejection((err) => {
console.error('caught', err);
});
function catchyFetch(...args) {
return CatchyPromise.resolve(fetch(...args));
}
呸,这很简单。
我正在开发一个到处都使用 what-wg fetch 的应用程序。我们以这种方式定义了默认的获取中间件和选项:
export function fetchMiddleware(response) {
return new Promise(resolve => {
resolve(checkStatus(response));
}).then(parseJSON);
}
export const fetchDefaults = {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
我们以这种方式使用默认的中间件/获取选项:
fetch('/api/specific/route', fetchDefaults)
.then(fetchMiddleware)
.then(function(data) {
// ... Dispatch case-specific fetch outcome
dispatch(specificRouteResponseReceived(data));
});
我们想为整个应用程序中的所有 fetch
用法 添加一个通用的后备捕获,换句话说,像这样:
export function fetchGenericCatch(function(error) {
showGenericErrorFlashMessage();
})
fetch('/en/api/user/me/preferences', fetchDefaults)
.then(fetchMiddleware)
.then(function(data) {
dispatch(userPreferencesReceived(data));
})
.catch(fetchGenericCatch);
大量代码重复。我们想要一个效用函数 / class 可以为我们完成所有这些,例如像这样工作的东西:
genericFetch('/api/specific/route') // bakes in fetchDefaults and fetchMiddleware and fetchGenericCatch
.then(function(data) {
dispatch(userPreferencesReceived(data));
}); // gets generic failure handler for free
genericFetch('/api/specific/route') // bakes in fetchDefaults and fetchMiddleware and fetchGenericCatch
.then(function(data) {
dispatch(userPreferencesReceived(data));
})
.catch(function(error) {
// ...
}); // short-circuits generic error handler with case-specific error handler
主要警告是通用 catch
必须链接 在 特定案例 then
s / catch
es 之后。
关于如何使用 whatwg-fetch / ES6 Promises 实现这一点的任何提示?
相关:
有类似的帖子,但它们似乎没有解决在所有非默认 then
s 和 catch
es 之后运行 的默认捕获的需要:
编辑 10 月 14 日:
可能重复:Promises and generic .catch() statements
我认为解决方案很简单:
export function genericFetch(url, promise, optionOverrides) {
const fetchOptions = {...fetchDefaults, ...optionOverrides};
return fetch(url, fetchOptions)
.then(fetchMiddleware)
.then(promise)
.catch(function(error) {
showGenericFlashMessage();
});
}
不需要特殊错误处理程序的用例可以简单地这样使用:
genericFetch('/api/url', function(data) {
dispatch(apiResponseReceived(data));
});
需要特殊捕获或更复杂链的用例可以传递完整的承诺:
genericFetch('/api/url', function(response) {
return new Promise(resolve, reject => {
dispatch(apiResponseReceived(data));
}).catch(nonGenericCaseSpecificCatch); // short-circuits default catch
});
只要错误处理程序是 DRY,拥有 WET 代码并不是最糟糕的选择。
fetch(...)
...
.catch(importedFetchHandler);
它不会导致任何问题,并且符合 Bluebird 和 V8 承诺的行为,其中存在未处理的拒绝事件以确保没有未捕获的承诺。
实现这一点的最简单方法是为 fetch
promise:
function CatchyPromiseLike(originalPromise) {
this._promise = originalPromise;
this._catchyPromise = Promise.resolve()
.then(() => this._promise)
.catch((err) => {
console.error('caught', err);
});
// every method but 'constructor' from Promise.prototype
const methods = ['then', 'catch'];
for (const method of methods) {
this[method] = function (...args) {
this._promise = this._promise[method](...args);
return this;
}
}
}
可以像
一样使用function catchyFetch(...args) {
return new CatchyPromiseLike(fetch(...args));
}
像这样的承诺有其天然的局限性。
如果转换为真正的承诺,副作用将被丢弃:
Promise.resolve(catchyFetch(...)).then(() => /* won't be caught */);
而且它不能很好地与异步链一起使用(这是对所有承诺的禁忌):
var promise = catchyFetch(...);
setTimeout(() => {
promise.then(() => /* won't be caught */);
});
Bluebird 是一个不错的选择,无需在那里发明轮子,功能就是它的优点。 Local rejection events 看起来正是需要的东西:
// An important part here,
// only the promises used by catchyFetch should be affected
const CatchyPromise = Bluebird.getNewLibraryCopy();
CatchyPromise.onPossiblyUnhandledRejection((err) => {
console.error('caught', err);
});
function catchyFetch(...args) {
return CatchyPromise.resolve(fetch(...args));
}
呸,这很简单。