我对javascript中的async await比较陌生,所以这个问题可能是我不知道的。
我有这个
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');
}
}
不知何故,我收到了这个疯狂的警告,我不知道我在哪里没有捕捉到错误。
当然,我让构建配置失败是为了测试错误,但我得到的错误不是正常的流程,而是:
(node:415) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Error while trying to analyze libs
我使用async await很好吗?有没有什么我应该遵循的模式来链接异步等待?
最奇怪的是foo函数工作得很好,这意味着失败。(500).send(‘res.status’);工作,并且我得到了响应
当我使用原生promises时,这个错误没有出现。
我真的困在这里了
发布于 2018-09-18 03:08:12
在使用async-await
扫描功能时,您将.then()
.catch()
瀑布与await
混合在一起。async-await
处理承诺的能力和.then()
一样好。因此,坚持使用一个流,并尝试在一个函数中混合这两个或在另一个函数中混合这两个流。
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;
}
}
发布于 2018-09-18 03:00:28
调用async
函数(这里是analyze
)将返回一个promise,它将根据async
函数的返回值或是否抛出错误来解决或拒绝。
现在,analyze
函数正在处理抛出的错误,但是当抛出错误时,它将返回一个Promise.reject()
。Promise.reject()
在这里是未处理的拒绝,这就是日志所描述的。
就同步函数而言,等效函数为
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中
try {
sync();
} catch (ex) {
console.error(ex); // not gonna throw another exception, otherwise the program might crash
}
现在,analyze
函数的此包装的等价物将使用另一个异步函数,或者更好,因为调用async
函数将返回Promise
,请使用Promise
的catch
方法
analyze()
.then(() => console.log('My work is done here'))
.catch(ex => console.error(ex)); // NOTE: not throwing another exception
更好的做法是在一开始就不返回来自catch
的拒绝,从而使analyze
,
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
}
}
发布于 2018-09-26 22:15:36
在analyze()中,返回的是Project.reject(),但analyze()是一个异步函数。因此,它会解析您返回的任何值,并拒绝您抛出的任何错误。
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函数将始终解析。试着这样做。
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)
传递了一个异步函数,它也不关心。它不会等待每个函数完成后才调用下一个函数。
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);
});
下面有两个变化
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。
https://stackoverflow.com/questions/52373878
复制相似问题