为了账号安全,请及时绑定邮箱和手机立即绑定

如果序列中的承诺之一抛出错误,则按顺序解决承诺并打破序列

如果序列中的承诺之一抛出错误,则按顺序解决承诺并打破序列

翻过高山走不出你 2023-03-10 15:51:23
假设我async设置了三个函数,如下所示:const stepOne = async () => { setTimeout(function() {  console.log("step 1")}, 3000)  }const stepTwo = async () => { throw new Error("Error at step two") }const stepThree = async () => { console.log("step 3") }我将如何按顺序执行所有这些函数并在 stepTwo 处打破承诺链,不允许 stepThree 函数运行?所以,正常顺序是这样的:stepOne --> stepTwo --> stepThree在 stepTwo 处抛出错误的序列:stepOne --> stepTwo在 stepTwo 抛出的错误需要在 end catch 块中被捕获。更新#1:错过了问题的关键要素。await 不能使用,因为这三个函数需要在非异步函数中调用。例子:const testFunc = () => {     resolve three promises   sequentially, break the promise chain when error is thrown   and ultimately, catch errors here     }
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

如果您解决承诺,您的代码将起作用stepOne,因为setTimeout只是将函数添加到堆栈而不是等待它解决。


如果您要返回一个 PromisestepOne并在之后解决它,console.log那么它将try catch等待stepOne并捕获错误stepTwo


这是您的代码示例


const stepOne = async () => {

    return new Promise((resolve, reject) => {

        setTimeout(function() {

            console.log("step 1")

            resolve(true);

        }, 3000)

    });

}


const stepTwo = async () => { throw new Error("Error at step two") }


const stepThree = async () => {

    return new Promise((resolve, reject) => {

        setTimeout(function() {

            console.log("step 3")

            resolve(true);

        }, 3000)

    });

}



(() => {

    stepOne()

        .then(stepTwo)

        .then(stepThree)

        .catch(error => {

            console.log(error);

        })  

})();

现在console.log看起来像这样


step 1

Error: Error at step two

    at stepTwo (/home/user/develop/test/stackoverflow.js:10:38)

    at processTicksAndRejections (internal/process/task_queues.js:93:5)


查看完整回答
反对 回复 2023-03-10
?
慕丝7291255

TA贡献1859条经验 获得超6个赞

请尝试以下代码。您需要等待每次调用(stepOne、stepTwo 和 stepThree),以便在出现异常时不会进行下一次调用。


try {

    await stepOne();

    await stepTwo();

    await stepThree()

} catch (error) {

    console.log(error);

}


查看完整回答
反对 回复 2023-03-10
?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

如果您的步骤是返回 Promise 的函数,您可以创建一个包装函数,它将按顺序调用每个步骤并在步骤失败时中止,并记录失败步骤的详细信息。


在此示例中,每个步骤失败的概率为五分之一。


// Make a step proc, that throws 1 time in 5

function createStep(index) {

    let error = (Math.random() < 0.2) ? new Error(`Step ${index+1} error`) : null ;

    return () => new Promise((resolve, reject) => setTimeout(error ? reject(error): resolve(`Step ${index+1} outcome`), 500));

}


async function runSteps(steps) {

   

   for(stepIndex = 0; stepIndex < steps.length; stepIndex++) {

       try {

         console.log(`Running step #${stepIndex+1}...`);

         let result = await steps[stepIndex]();

         console.log(`Step result:`, result);

       } catch (e) { 

         console.error(`An error occurred at step #${stepIndex+1}:`, e.message);

         break;

       }

       if (stepIndex === (steps.length -1) ) {

          console.log("All steps completed successfully");

       }

   }

}


let steps = Array.from( { length: 3 }, (v,k) => createStep(k));

runSteps(steps);


查看完整回答
反对 回复 2023-03-10
  • 3 回答
  • 0 关注
  • 153 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号