处理被拒绝的承诺而不会陷入混乱

时间:2020-05-31 20:33:58

标签: javascript node.js promise async-await

我有一个简单的功能,看起来类似于以下内容

const foo = (bar) => {

return ![val1, val2].includes(bar) ? await apiRequest :
await apiRequest + await apiRequest2

}

apiRequest返回一个数字。

此功能被处理许多功能错误的功能所包围。

但是对于这个特定的功能,我不只是想在三元第二部分中的一个apiRequests失败的情况下向用户返回错误。

const foo = (bar) => {

return ![val1, val2].includes(bar) ? await apiRequest :
await apiRequest + await apiRequest2

// intended logic for second part of ternary
if apiRequest and apiRequest resolve, return apiRequest + apiRequest2
if apiRequest fails, return apiRequest2
if apiRequest 2 fails, return apiRequest
}

我不确定我应该怎么做。也许我可以用try and catch围绕每个部分,然后在catch语句中可以尝试逻辑的下一部分?

在这种情况下,我觉得我最终将获得一个超级凌乱的功能

2 个答案:

答案 0 :(得分:1)

首先,onPressed: () async { if(_formKey.currentState.validate()){ setState(()async{ loading = true; dynamic result = await _auth.signInWithEmailAndPassword(email, password); if(result == null) { loading = false; error = 'Could not sign in with those credentials'; }); } } } 必须出现在await函数中,因此问题中的代码无法运行。

如果我理解正确,那么您仍然希望函数在 both 都拒绝时返回一个被拒绝的承诺。

您可以定义一个效用函数,该函数将一个数组作为promise并返回一个promise,该promise仅在给定promise拒绝 all 时拒绝(因为拒绝第一个promise的原因)。在所有其他情况下,它将解析为具有单个已实现值的数组,或者在拒绝相应的Promise时解析为默认值。

此实用程序功能可能如下所示:

async

然后您的函数可能如下所示:

async function fulfilled(promises, defValue) {
    const res = await Promise.allSettled(promises);
    if (res.every(p => p.status == "rejected")) throw res[0].reason;
    return res.map(p => p.status == "fulfilled" ? p.value : defValue);
}

答案 1 :(得分:-1)

您可以尝试

  defaultval="no value"
    const foo = async (bar,apiCalls,defaultval) => {
        var finalresult= await Promise.allSettled(apiCalls)
    .then(resp=>resp.map(p=>p.status==='fulfilled'?p.value:defaultval))
    .then((res)=>{
        var finalnumber=res.filter(x=>x!='no value')
        return finalnumber.length==0?defaultval:finalnumber.reduce((a, b) => a + b)
    })
        return  ![val1, val2].includes(bar) ? apiRequest : finalresult
    }

由@trincol回答,如果两个诺言之一失败,它将提醒添加到默认值;如果所有诺言失败,它将抛出错误并且不返回值,也不会返回默认值。 所以我调整了这样的代码

defaultval="no value"

async function fulfilled(apiCalls,defaultval) {
    const res = await Promise.allSettled(apiCalls);
    return res.map(p => p.status == "fulfilled" ? p.value:defaultval)
}

const foo = async (bar,defaultval) => {
   var result= await fulfilled([apiRequest, apiRequest2])
   var numb=result.filter(x=>x!=defaultval)
   return ![val1, val2].includes(bar) ? apiRequest :(numb.length==0?defaultval:numb.reduce((a, b) => a + b)
   )
}