首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >取消处理拒绝承诺异步等待链

取消处理拒绝承诺异步等待链
EN

Stack Overflow用户
提问于 2018-09-18 02:37:25
回答 3查看 516关注 0票数 7

我对javascript中的async await比较陌生,所以这个问题可能是我不知道的。

我有这个

代码语言:javascript
复制
  async function foo(req, res, next) {
    try {
      await scan(req.params.stack);
      res.send('ok');
    } catch (err) {
      res.status(500).send('fail');
    }
  }

async function scan(stack) {
  try {
    const libs = [1,2,3];
    const promises = libs.map(async l => analyze(stack, l)
      .catch((err) => { throw new Error(err); }));
    return q.allSettled(promises)
      .then((results) => {
        const rejected = results.filter(r => r.state === 'rejected');
        if (rejected.length === results.length) throw new Error('Failed');
        return results;
      })
      .catch((err) => {
        throw new Error(err);
      });
  } catch (err) {
    throw new Error(err);
  }
}

async function analyze(stack, libraries) {
  try {
    const config = await buildConfiguration(stack, libraries);
    return await databaseInsertion(vulnsObject);
  } catch (err) {
    return Promise.reject('Error while trying to analyze libs');
  }
}

不知何故,我收到了这个疯狂的警告,我不知道我在哪里没有捕捉到错误。

当然,我让构建配置失败是为了测试错误,但我得到的错误不是正常的流程,而是:

代码语言:javascript
复制
(node:415) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Error while trying to analyze libs

我使用async await很好吗?有没有什么我应该遵循的模式来链接异步等待?

最奇怪的是foo函数工作得很好,这意味着失败。(500).send(‘res.status’);工作,并且我得到了响应

当我使用原生promises时,这个错误没有出现。

我真的困在这里了

EN

回答 3

Stack Overflow用户

发布于 2018-09-18 03:08:12

在使用async-await扫描功能时,您将.then() .catch()瀑布与await混合在一起。async-await处理承诺的能力和.then()一样好。因此,坚持使用一个流,并尝试在一个函数中混合这两个或在另一个函数中混合这两个流。

代码语言:javascript
复制
async foo(req, res, next) {
    try {
        await scan(req.params.stack);
        res.send('ok');
    } catch (err) {
        res.status(500).send('fail');
    }
}

async scan(stack) {
  try {
    const libs = [1,2,3];

    // This libs.map functions return promise. then why not use await?
    const promises = await libs.map(async l => analyze(stack, l);

    // Again q.allSettled returns promise, use await here too
    let results = await q.allSettled(promises);

    const rejected = results.filter(r => r.state === 'rejected');

    if (rejected.length === results.length) throw new Error('Failed');

    return results;

  }

  // If any promise call reject function will be in catch
  catch (err) {
    throw new Error(err);
  }
}

async function analyze(stack, libraries) {
    try {
        const config = await buildConfiguration(stack, libraries);
        return await databaseInsertion(vulnsObject);
    }
    catch (err) {
        console.log(err);
        return null;
    }
}
票数 4
EN

Stack Overflow用户

发布于 2018-09-18 03:00:28

调用async函数(这里是analyze)将返回一个promise,它将根据async函数的返回值或是否抛出错误来解决或拒绝。

现在,analyze函数正在处理抛出的错误,但是当抛出错误时,它将返回一个Promise.reject()Promise.reject()在这里是未处理的拒绝,这就是日志所描述的。

就同步函数而言,等效函数为

代码语言:javascript
复制
function sync() {
  try {
    // do something dangerous
  } catch (ex) {
    throw Error('Something bad happened'); // this error is still being thrown and nobody is handling it
  }
}

要处理此错误,可以在调用sync时执行以下操作,将其包装在try and catch中

代码语言:javascript
复制
try {
  sync();
} catch (ex) {
  console.error(ex); // not gonna throw another exception, otherwise the program might crash
}

现在,analyze函数的此包装的等价物将使用另一个异步函数,或者更好,因为调用async函数将返回Promise,请使用Promisecatch方法

代码语言:javascript
复制
analyze()
  .then(() => console.log('My work is done here'))
  .catch(ex => console.error(ex)); // NOTE: not throwing another exception

更好的做法是在一开始就不返回来自catch的拒绝,从而使analyze

代码语言:javascript
复制
async function analyze(stack, libraries) {
  try {
    const config = await buildConfiguration(stack, libraries);
    return await databaseInsertion(vulnsObject);
  } catch (err) {
    console.error(err); // not eating up good errors with something vague is always good
    return null; // or something else to signify that insert failed
  }
}
票数 1
EN

Stack Overflow用户

发布于 2018-09-26 22:15:36

在analyze()中,返回的是Project.reject(),但analyze()是一个异步函数。因此,它会解析您返回的任何值,并拒绝您抛出的任何错误。

代码语言:javascript
复制
    async function analyze(stack, libraries) {
        try {
            const config = await buildConfiguration(stack, libraries);
            return await databaseInsertion(vulnsObject);
        } catch (err) {
            return Promise.reject('Error while trying to analyze libs');
        }
    }

因此,当analyze函数捕获到错误时,您正在创建一个拒绝,但随后会解决该函数。所以Promise.reject('Error while trying to analyze libs');没有被处理。由于异步函数总是返回一个promise,该promise将解析您返回的所有内容,并拒绝您抛出的任何内容,因此analyze函数将始终解析。试着这样做。

代码语言:javascript
复制
    async function analyze(stack, libraries) {
        try {
            const config = await buildConfiguration(stack, libraries);
            return await databaseInsertion(vulnsObject);
        } catch (err) {
            throw Error('Error while trying to analyze libs');
        }
    }

我在这段代码中看到的另一个可能的问题是,即使你向map(async func)传递了一个异步函数,它也不关心。它不会等待每个函数完成后才调用下一个函数。

代码语言:javascript
复制
const promises = libs.map(async l => analyze(stack, l)
      .catch((err) => { throw new Error(err); }));
    return q.allSettled(promises)
      .then((results) => {
        const rejected = results.filter(r => r.state === 'rejected');
        if (rejected.length === results.length) throw new Error('Failed');
        return results;
      })
      .catch((err) => {
        throw new Error(err);
      });

下面有两个变化

代码语言:javascript
复制
const promises = libs.map(async l => await analyze(stack, l)
      .catch((err) => { throw new Error(err); }));
    return q.allSettled( await promises)
      .then((results) => {
        const rejected = results.filter(r => r.state === 'rejected');
        if (rejected.length === results.length) throw new Error('Failed');
        return results;
      })
      .catch((err) => {
        throw new Error(err);
      });

我在analyze函数之前添加了一个await,并在将promises变量传递到q.allSettled()之前添加了一个await。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52373878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档