当前位置: 首页 > 知识库问答 >
问题:

按顺序解析promise,如果序列中的promise之一抛出错误,则中断序列[重复]

慕震博
2023-03-14

假设我有三个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") }

我将如何顺序执行所有这些函数,并在第二步打破promise链,不允许第三步函数永远运行?

所以

正常的顺序是这样的:第一步--

在步骤二抛出错误的序列:步骤一--

第二步抛出的错误需要在end catch块中捕获。

更新#1:错过了这个问题的一个关键元素。wait不能被使用,因为这三个函数需要在一个不是异步的函数中调用。

例子:

const testFunc = () => { 
  
  resolve three promises 
  sequentially, break the promise chain when error is thrown 
  and ultimately, catch errors here
   
  }

共有3个答案

轩辕远
2023-03-14

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

在本例中,每一步失败的几率为1/5。

// 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-14

请尝试下面的代码。您需要等待每次呼叫(第一步、第二步和第三步),以便在出现任何异常时,不会进行下一次呼叫。

try {
    await stepOne();
    await stepTwo();
    await stepThree()
} catch (error) {
    console.log(error);
}
姚麒
2023-03-14

如果您要从stepOne解析promise,那么您的代码就可以工作,因为setTimeout只是将函数添加到堆栈中,而不是等待它解析。

如果您要从stepOne返回一个Promise并在console.log之后解决它,那么try cat将等待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)
 类似资料:
  • 我这里的问题是,获取promise在当前文本之前创建了几个字符,然后在最后创建的promise之后解析。我需要解决的最后一个promise的最新或取消以前的promise时,我改变了文本。 我希望结果总是最新的。 我查找了一些搜索栏示例,但什么也没找到。 我很确定解决方案是保存以前的promise,如果在你创建一个新promise时它仍然悬而未决,就取消它,但是我不知道如何取消promise。 谢

  • 考虑以下以串行/顺序方式读取文件数组的代码。返回一个promise,该promise仅在按顺序读取所有文件后才解析。 上面的代码可以工作,但我不喜欢必须为事情按顺序发生而做递归。有没有更简单的方法可以重写这段代码,使我不必使用我怪异的函数? 最初,我尝试使用,但这导致所有调用并发发生,这不是我想要的:

  • 我对promise不熟悉。我查找了按顺序执行promise的示例,但没有找到与我的应用程序类似的示例。 我的问题是,我想按照一定的顺序解决promise,但也要捕获promise解决时的所有结果。通过查找例子。我已经创建了这个问题的简化版本。 我能够创建一个函数doWork(),但问题是它所做的只是按顺序解决promise,而没有捕获结果。 理想情况下,我想要一个返回promise的函数,该函数将

  • 我对不同的API(由delayedPromise函数模拟)执行多个请求,每个请求都需要一定的时间才能完成。如果其中一个满足,我返回它解析的值,就这样。我现在一个接一个地做这些,因为第一个请求是最准确的,而第二个则不太准确,等等。因此,如果第一个请求失败,第二个满足,我将返回第二个请求 为了加快速度,我考虑将这些请求并行化。为了实现这一点,我正在创建一个数组,它持有promise,它等待第一个元素的

  • 我正在努力在以下任务中发送多个AJAX调用。API返回有两个参数:和,并返回指定用户的最后10条消息,从指定的偏移量开始。如果偏移量大于用户的消息总数,API将返回空字符串。 我编写了一个函数,返回一个单独的promise,为指定的和获取10条消息。 我需要使用为多个运行并行任务,但是我无法为每个运行并行子任务(每次将

  • 问题内容: 在promise库 Q中 ,您可以执行以下操作以顺序链接promise: 但是,以下命令不适用于 $ q : 问题答案: 只需使用$ q.when()函数: 注意:foo必须是工厂,例如