Javascript 这是一个好的';idea&x27;使用async/await防止嵌套承诺?

Javascript 这是一个好的';idea&x27;使用async/await防止嵌套承诺?,javascript,node.js,promise,nested,Javascript,Node.js,Promise,Nested,我有一些困难与嵌套的承诺(如下)。 目前,我正在catch中使用异步函数来触发身份验证错误s 但这真的是一个好方法吗?难道没有更好的方法吗 函数必须发送POST请求。如果抛出身份验证错误,则抛出登录(),否则抛出错误。 如果login()已完成:重试POST(然后返回结果),否则抛出错误 函数getSomeData(){ 回帖('mySpecialMethod'); } 函数登录(){ 常量参数={/*某些参数*/} return post('myLoginMethod',params)。然后(

我有一些困难与嵌套的承诺(如下)。 目前,我正在catch中使用
异步函数
来触发
身份验证错误
s

但这真的是一个好方法吗?难道没有更好的方法吗

函数必须发送POST请求。如果抛出
身份验证错误
,则抛出
登录()
,否则抛出错误。 如果
login()
已完成:重试POST(然后返回结果),否则抛出错误

函数getSomeData(){ 回帖('mySpecialMethod'); } 函数登录(){ 常量参数={/*某些参数*/} return post('myLoginMethod',params)。然后(result=>{ /*一些加工*/ 返回{success:true}; }); } 常量登录错误=[1101]; 功能柱(方法、参数、测量){ 常量选项=/*为简洁起见隐藏*; 退货申请(选项) //如果身份验证错误| |抛出错误,请登录并重试 .catch(异步ex=>{ 常数err=ex.error.error | | ex.error 如果(loginError.includes(err.code)&&&!isRetry){//如果无法登录,则阻止无限循环->如果已经重试,则不重试 等待登录(); 返回post(方法,参数,真) }否则{ 犯错误; } }) //如果没有错误,则返回结果 。然后(数据=>{ //来自“返回请求(选项)”或“返回帖子(方法、参数、真)”的数据 返回数据.result }); } 使用
getSomeData.then(data=>{/*对data*/}做点什么);

一般来说,这不是什么大问题。您可以像这样链接/封装异步调用

说到逻辑,这取决于你的需要。我认为在调用任何需要身份验证的API方法之前,应该检查用户的登录状态

。。。但这真的是一个好方法吗?难道没有更好的方法吗

不,这不是个好主意,因为它很痛

您正在混合2个可交换的概念,
Promise.then/catch
async/await
。将它们混合在一起会产生可读性开销,其形式为

任何阅读您的代码的人,包括您在内,都需要在异步流(
.then/.catch
)和同步流(
async/await
)之间不断切换

使用一个或另一个,最好是后者,因为它更可读,主要是因为它的同步流

虽然我不同意您处理登录的方式,但以下是我将如何重写您的代码,以使用
async/await
try…catch
进行异常处理:

function getSomeData() {
    return post('mySpecialMethod')
}

async function login() {
    const params = { } // some params

    await post('myLoginMethod', params)

    return { success: true }
}

const loginError = [1, 101]

async function post(method, params, isRetry) {
    const options = {} // some options

    try {
        const data = await request(options)

        return data.result
    } catch (ex) {
        const err = ex.error.error || ex.error

        if (err) throw err

        if (loginError.includes(err.code) && !isRetry) {
            await login()

            return post(method, params, true)
        }

        throw err
    }
}

显然,我不能/没有测试上述内容。

我建议,对于复杂的逻辑,至少可以使用async/await语法

当然.then()etc是完全有效的,但是您会发现回调的嵌套很难处理

我的规则(就像编程中的很多事情一样)是使用上下文来做出决定。然后()在处理数量有限的承诺时会很好地工作。当你处理更复杂的逻辑时,这会变得很尴尬

使用async/await进行更复杂的逻辑可以使您的代码结构更像同步代码,因此更直观、更可读

下面显示了两种方法的示例(具有相同的基本目标)。我认为异步/等待版本更具可读性

Async/await还可以简化异步任务上的循环,您可以使用for循环或for。。。使用wait进行循环,任务将按顺序执行

函数异步操作(结果){
返回新承诺(resolve=>setTimeout(resolve,1000,result));
}
异步函数TestAsyncOperationsWait(){
const result1=等待异步操作(“某些结果1”);
log(“TestAsyncOperationsWait:Result1:”,Result1);
const result2=等待异步操作(“某些结果2”);
log(“TestAsyncOperationsWait:Result2:”,Result2);
const result3=等待异步操作(“某些结果3”);
log(“TestAsyncOperationsWait:Result3:”,Result3);
}
函数testAsyncOperationsThen(){
返回asyncOperation(“testAsyncOperationsThen:Some result 1”)。然后(result1=>{
log(“testAsyncOperationsThen:Result1:”,Result1);
返回asyncOperation(“testAsyncOperationsThen:Some result 2”)。然后(result2=>{
log(“testAsyncOperationsThen:Result2:”,Result2);
返回asyncOperation(“testAsyncOperationsThen:Some result 3”)。然后(result3=>{
log(“testAsyncOperationsThen:Result3:”,Result3);
})
})
})
}
异步函数测试(){
等待TestSyncOperationsThen();
等待测试同步操作等待();
}

test()还值得探索提供重试功能的库


类似于
https://www.npmjs.com/package/async-retry

这不起作用:您正在执行“无错误返回结果”,即使有错误,并且您从重试中获得了一些信息,然后再次访问
.result