当单个承诺解决或拒绝时,如何让我的程序保持 运行?

How do I get my program to keep running when a single promise resolves or rejects?

如果一切正常,我希望我的程序能够解决问题,然后使用 for 循环进行下一个测试;或者,如果出现错误,我希望它再次 运行。但是如果它遇到六次错误,我希望它放弃并尝试循环的下一个函数。

我的期望:

index is 0 and loop is 0
index is 1 and loop is 0
index is 2 and loop is 0
index is 3 and loop is 0
index is 4 and loop is 0
index is 5 and loop is 0
5 is too many errors
[printed error]
index is 0 and loop is 7
index is 1 and loop is 7
index is 2 and loop is 7
index is 3 and loop is 7
index is 4 and loop is 7
index is 5 and loop is 7
5 is too many errors
[printed error] ..  and so on

我实际得到的是:

index is 0 and loop is 0
index is 1 and loop is 0
index is 2 and loop is 0
index is 3 and loop is 0
index is 4 and loop is 0
index is 5 and loop is 0
5 is too many errors
(node:29808) UnhandledPromiseRejectionWarning: undefined
(node:29808) UnhandledPromiseRejectionWarning: Unhandled promise rejection.

代码:

const hello = async (index, i) => {
  return new Promise(async (resolve, reject) => {
        console.log(`index is ${index} and loop is ${i}`)
        if(index === 5){
            reject(console.log(`${index} is too many errors`)) // this runs
        } else if (index === 6){
            resolve(console.log("I realize it won't ever resolve :) ")) 
        }
        else{
            hello(++index, i)
        }
    })
};

const loop_function = async () => {
    return new Promise (async(res, rej)=>{
        for (var i = 0; i <= 35; i += 7) {
            try{
                await hello(0, i)
            } catch(err){
                console.log("caught an error!") // this does not run
            }
        }
        res(console.log("resolved everything")) // this does not run
    })
}


const final = async () =>{
    await loop_function()
    console.log("loop_function complete") // this does not run
}


final();

问题是您的递归 hello(++index, i) 调用被忽略了——您从不使用它的结果值。它可能是一个被拒绝的承诺(然后你会收到 "unhandled rejection" 警告),更糟糕的是,你永远不会解决你正在构建的承诺。但是你应该避免 Promise constructor antipattern 无论如何!

async function hello(index, i) {
    console.log(`index is ${index} and loop is ${i}`)
    if (index === 5) {
        throw new Error(`${index} is too many errors`)
    } else if (index === 6) {
        return "I realize it won't ever resolve :)"
    } else {
        return hello(++index, i)
//      ^^^^^^ this is essential! Or at least `await` the returned promise
    }
}

async function loop() {
    for (var i = 0; i <= 35; i += 7) {
        try {
            await hello(0, i)
        } catch(err) {
            console.log("caught an error!", err)
        }
    }
    console.log("resolved everything")
}

loop().then(() => {
    console.log("loop_function complete")
}, () => {
    console.log("unhandled error")
})

要修改的内容:

  1. 从两个函数中清除 new Promise() 包装器;它们是不必要的,因为 AsyncFunctions 保证 return Promise 并且在内部你可以简单地 return/throw.
  2. 一定要return hello(++index, i)以便return递归的每一层的结果到它的上层,并最终到达最顶层的原始调用者。
  3. 当满足(index >= 5)条件时,直接抛出一个Error;不需要记录,因为调用者的(loop_function 的)catch 块将进行记录。

所以,你可能会得到:

const hello = async (index, i) => {
 console.log(`index is ${index} and loop is ${i}`);
 if(index >= 5) {
  throw new Error(`${index} is too many errors`);
 } else {
  return hello(++index, i);
 }
};
const loop_function = async () => {
 for (var i = 0; i <= 35; i += 7) {
  try {
   await hello(0, i);
  } catch(err) {
   console.log(err.message);
  }
 }
 console.log("resolved everything");
}
const final = async () =>{
 await loop_function();
 console.log("loop_function complete");
}
final();