以下内容有效:
new Promise<void>((resolve, reject) => {
reject()
})
.then(() => {})
.catch(() => {})
但我可能并不总是关心这个错误。有没有办法让捕获可选?
我尝试了这个,但它没有工作:
new Promise<void>((resolve, reject?) => {
if (reject) reject()
})
.then(() => {})
Error: Uncaught (in promise): undefined
答案 0 :(得分:1)
你可以解决错误何时你不关心的事情。如果您的catch返回除被拒绝的承诺之外的任何内容,则该错误不会在链中传播。
const ignorableError = new Error("I don't care about this error");
const myPromise = new Promise((resolve, reject) => {
reject(ignorableError);
})
.then(() => {})
.catch(error => {
if(error == ignorableError) {
console.log("Error ignored");
return;
}
// Do something else...
});
myPromise.then(() => console.log("Success"))
&#13;
答案 1 :(得分:1)
有没有办法让捕捉可选?
没有。如果您使用的承诺可能有误,则需要处理(或将其传播给您的调用者)。
当然,如果您自己创建承诺,拒绝它是可选的,您可以选择永不拒绝您的承诺,这样您就不需要处理任何错误。但是如果您使用的承诺中存在错误,并且您想忽略它们,则必须明确地这样做。只需写下
somePromise.catch(e => void e);
// or () => { /* ignore */ }
// or function ignore() {}
答案 2 :(得分:0)
我试图解决相同的问题,最后提出了以下实用程序:
/**
* wraps a given promise in a new promise with a default onRejected function,
* that handles the promise rejection if not other onRejected handler is provided.
*
* @param customPromise promise to wrap
* @param defaultOnRejected default onRejected function
*/
export function promiseWithDefaultOnRejected(customPromise: Promise<any>, defaultOnRejected: (_: any) => any): Promise<any> {
let hasCatch = false;
function chain(promise: Promise<any>) {
const newPromise: Promise<any> = new Promise((res, rej) => {
return promise.then(
res,
function(value) {
if (hasCatch) {
rej(value);
} else {
defaultOnRejected(value);
}
},
);
});
const originalThen = newPromise.then;
newPromise.then = function(onfulfilled?: any, onrejected?: any) {
const result: Promise<any> = originalThen.call(newPromise, onfulfilled, onrejected);
if (typeof onrejected === 'function') {
hasCatch = true;
return result;
} else {
return chain(result);
}
};
return newPromise;
}
return chain(customPromise);
}
此实用程序使您可以使用defaultOnRejected
函数包装诺言,如果没有提供其他处理程序,该函数将处理被拒绝的诺言。例如:
const dontCare = promiseWithDefaultOnRejected(Promise.reject("ignored"), () => {});
那个承诺永远不会抛出“未处理的承诺拒绝”,您可以按以下方式使用它:
dontCare.then(x=>console.log("never happens")).catch(x=>console.log("happens"));
或
dontCare.then(x=>console.log("never happens"), x=>console.log("happens"));
或根本没有onRejected
处理程序:
dontCare.then(x=>console.log("never happens")).then(x=>console.log("also never happens"));
此实用程序的一个问题是,它在使用async / await语法时无法正常工作:您仍然需要按以下方式处理“捕获”路径:
async () => {
try {
await promiseWithDefaultOnRejected(Promise.reject("ignored"), () => {});
} catch (e) {
console.log("happens");
}
}
答案 3 :(得分:-1)
让我试着描述你的情况:
您有一个获取用户信息的服务和一个使用该服务的名为getUser
的函数。当服务因任何原因失败时,getUser
没有可用的用户。 getUser
的结果在代码中使用了很多次,具有以下情况:
使用getUser
结果时,您可能希望运行所有3个函数,其中包含2个函数或仅包含1个函数。
当前getUser
返回Promise,此类型似乎不适合您的情况。主要是因为拒绝承诺并且没有捕获它将导致未经处理的承诺拒绝。并且因为如果你想在用户可用的情况下运行代码,它会使函数复杂化(他们都必须检查结果而不是假设用户是否可用)。
也许您可以尝试以下代码,请小心在not available
块中进行假设,这可能是由于任何错误造成的。例如:它并不意味着用户不存在,因为它可能是网络错误。
在示例中使用了getUser
,但可以是任何返回承诺的函数,在拒绝时假定not available
。
const isAvailable = promise => {
//do not expose NOT_AVAILABLE outside this function
const NOT_AVAILABLE = {type:"not available"};
//no uncaught promise rejection errors by VM
const savePromise = promise.catch(x=>x);
return {
available:fn=>
promise
.catch(e=>Promise.reject(NOT_AVAILABLE))
.then(fn)
.catch(
e=>
(e===NOT_AVAILABLE)
? undefined//ignore
: Promise.reject(e)//re throw, error is not from service
),
//call not available with the promise if promise rejects
notAvailable:fn=>promise.catch(()=>fn(promise)),
catchError:promise.catch.bind(promise)
};
}
const service = arg =>
(arg===1)
? Promise.resolve(arg)
: Promise.reject(arg)
const getUser = arg => isAvailable(service(arg));
var user = getUser(2);
//if service failed available will be skipped
user.available(
user=>console.log("skipped:",user)
);
//both catch and notAvailable will be called
user.notAvailable(
arg=>console.log("not available:",arg)
);
user.notAvailable(
arg=>console.log("still not available:",arg)
);
//not handling catchError does not cause uncaught promise exception
// but you can inspect the error
// user.catchError(
// err=>console.log("error is::",err)
// );
var user = getUser(1);
//you can call available on user multiple times
user.available(
user=>console.log("got user:",user)
);
user.available(
user=>Promise.resolve(user)
.then(user=>console.log("still got user:",user))
.then(x=>Promise.reject("have to catch this one though"))
.catch(e=>console.log("ok, got error trying to run available block:",e))
);
//showing you can inspect the error
var user = getUser(5);
user.catchError(err=>console.log("error from service:",err));
&#13;