javascript承诺中的可选捕获

javascript承诺中的可选捕获,javascript,typescript,promise,es6-promise,Javascript,Typescript,Promise,Es6 Promise,以下各项有效: new Promise<void>((resolve, reject) => { reject() }) .then(() => {}) .catch(() => {}) 新承诺((解决、拒绝)=>{ 拒绝 }) .然后(()=>{}) .catch(()=>{}) 但我可能并不总是关心错误。有没有办法让捕获成为可选的 我试过了,但没用: new Promise<void>((resolve, re

以下各项有效:

new Promise<void>((resolve, reject) => {
      reject()
    })
    .then(() => {})
    .catch(() => {})
新承诺((解决、拒绝)=>{
拒绝
})
.然后(()=>{})
.catch(()=>{})
但我可能并不总是关心错误。有没有办法让捕获成为可选的

我试过了,但没用:

new Promise<void>((resolve, reject?) => {
      if (reject) reject()
    })
    .then(() => {})
新承诺((解决、拒绝?)=>{
如果(拒绝)拒绝()
})
.然后(()=>{})

错误:未捕获(承诺中):未定义让我试着描述一下您的情况:

您有一个获取用户信息的服务和一个使用该服务的名为
getUser
的函数。当服务因任何原因失败时,
getUser
没有可用的用户。在以下情况下,
getUser
的结果在代码中被多次使用:

  • 用户可以运行函数(代码块)
  • 用户无法运行函数(代码块)
  • 运行带有错误/拒绝服务的函数
  • 使用
    getUser
    result时,您可能希望运行所有3个函数,其中两个函数的组合或仅一个函数

    Current
    getUser
    返回一个承诺,这种类型似乎不适合您的情况。主要是因为拒绝承诺而不遵守承诺会导致未经处理的承诺拒绝。因为如果您想在用户可用或不可用的情况下运行代码,则会使函数复杂化(它们都必须检查结果,而不是假设用户可用或不可用)

    也许您可以尝试以下代码,请小心在
    不可用
    块中进行假设,这可能是由于任何错误造成的。例如:这并不意味着用户不存在,因为这可能是网络错误

    在本例中,使用了
    getUser
    ,但可以是任何函数,该函数返回一个承诺,其中假定拒绝时
    不可用

    const isAvailable=promise=>{
    //不要暴露此功能之外的不可用项
    const NOT_AVAILABLE={type:“NOT AVAILABLE”};
    //VM没有未捕获的承诺拒绝错误
    const savePromise=promise.catch(x=>x);
    返回{
    可用:fn=>
    承诺
    .catch(e=>Promise.reject(不可用))
    .然后(fn)
    .接住(
    e=>
    (e==不可用)
    ?未定义//忽略
    :Promise.reject(e)//重新抛出,错误不是来自服务
    ),
    //如果承诺被拒绝,则呼叫不可用
    notAvailable:fn=>promise.catch(()=>fn(promise)),
    catchError:promise.catch.bind(promise)
    };
    }
    常量服务=arg=>
    (arg==1)
    ? 承诺。解决(arg)
    :承诺。拒绝(arg)
    const getUser=arg=>isAvailable(服务(arg));
    var user=getUser(2);
    //如果服务失败,将跳过可用服务
    user.available(
    user=>console.log(“跳过:”,用户)
    );
    //catch和notAvailable都将被调用
    user.notAvailable(
    arg=>console.log(“不可用:”,arg)
    );
    user.notAvailable(
    arg=>console.log(“仍然不可用:”,arg)
    );
    //不处理catchError不会导致未捕获的承诺异常
    //但是您可以检查错误
    //user.catchError(
    //err=>console.log(“错误为::”,err)
    // );
    var user=getUser(1);
    //您可以多次呼叫用户上的available
    user.available(
    user=>console.log(“获取用户:”,用户)
    );
    user.available(
    user=>Promise.resolve(用户)
    .then(user=>console.log(“仍然得到用户:”,user))
    .then(x=>Promise.reject(“必须抓住这个”))
    .catch(e=>console.log(“确定,尝试运行可用块时出错:”,e))
    );
    //显示您可以检查错误
    var user=getUser(5);
    
    user.catchError(err=>console.log(“来自服务的错误:”,err))当错误是您不关心的事情时,您可以解决。如果catch返回的不是被拒绝的承诺,那么错误不会沿着链传播

    const ignorableError=新错误(“我不在乎这个错误”);
    const myPromise=新承诺((解决、拒绝)=>{
    拒绝(忽略错误);
    })
    .然后(()=>{})
    .catch(错误=>{
    如果(错误==ignorableError){
    console.log(“忽略错误”);
    返回;
    }
    //做点别的。。。
    });
    myPromise.then(()=>console.log(“成功”))
    有没有办法让捕获成为可选的

    不可以。如果您使用的承诺可能会出错,则需要处理该承诺(或将其传播给调用方)

    当然,如果您自己创建了承诺,拒绝它是可选的,您可以选择从不拒绝您的承诺,这样您就不需要处理任何错误。但是,如果您正在使用的承诺中存在错误,并且您希望忽略它们,那么您必须明确地这样做。只要写

    somePromise.catch(e => void e);
    // or             () => { /* ignore */ }
    // or             function ignore() {}
    

    我试图解决同样的问题,最后得出以下结论:

    /**
    *使用默认的onRejected函数将给定的承诺包装到新的承诺中,
    *如果未提供其他onRejected处理程序,则处理承诺拒绝。
    *
    *@param custom承诺包装
    *@param defaultOnRejected默认onRejected函数
    */
    导出函数promiseWithDefaultOnRejected(customPromise:Promise,defaultOnRejected:(uu2;:任意)=>any):Promise{
    让hasCatch=false;
    功能链(承诺:承诺){
    const newPromise:Promise=新承诺((res,rej)=>{
    回报你的承诺(
    物件,
    函数(值){
    if(hasCatch){
    rej(价值);
    }否则{
    defaultOnRejected(值);
    }
    },
    );
    });
    const originalThen=newPromise.then;
    newPromise.then=函数(onCompleted?:any,onrejected?:any){
    const result:Promise=originalThen.call(newPromise、oncompleted、onrejected);
    if(typeof onrejected==='function'){
    hasCatch=true;
    返回结果;
    }否则{
    返回链(结果);
    }
    };
    回报新的承诺;
    }
    退货链(客户承诺);
    }
    

    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"));
    
    dontCare.then(x=>console.log("never happens")).then(x=>console.log("also never happens"));
    
    async () => {
      try {
        await promiseWithDefaultOnRejected(Promise.reject("ignored"), () => {});
      } catch (e) {
        console.log("happens");
      }
    }