我刚开始使用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];
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
我使用异步等待好吗?我应该遵循什么模式才能将异步链式等待?
疯狂的是foo函数运行良好,这意味着res.status。(500).send('fail');工作,我得到回应
当我使用正常的诺言时,不会出现此错误。
我真的被困在这里
答案 0 :(得分:4)
使用CREATE TABLE foo (a varchar(4000), a_ax AS (IIF(PATINDEX('%bar%', a) > 0, SUBSTRING(a, PATINDEX('%bar%', a), 42), '')))
CREATE INDEX foo_x ON foo(a_ax)
扫描功能时,您正在将async-await
.then()
瀑布与.catch()
混合在一起。 await
处理的承诺与async-await
一样好。因此,请坚持使用一种流程,并尝试将一种功能或另一种功能混合使用。
.then()
答案 1 :(得分:1)
调用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
}
}
要处理此错误,您可以在调用同步时执行以下操作,将其包装在try中,然后再次捕获
try {
sync();
} catch (ex) {
console.error(ex); // not gonna throw another exception, otherwise the program might crash
}
现在,等效于analyze
函数的此包装将使用另一个异步函数,或者更好,因为调用async
函数将返回一个Promise
,请使用{{1} } catch
Promise
更好的做法是首先不返回analyze()
.then(() => console.log('My work is done here'))
.catch(ex => console.error(ex)); // NOTE: not throwing another exception
的拒绝,从而使catch
,
analyze
答案 2 :(得分:0)
在analyzer()中,您将返回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');
}
}
因此,当analytics函数遇到错误时,您将创建拒绝项,然后再解决该函数。因此Promise.reject('Error while trying to analyze libs');
未得到处理。由于异步函数总是返回一个承诺,该承诺将根据您返回的内容进行解析,并拒绝您所抛出的任何内容,因此您的analyse函数将始终进行解析。尝试做这个...
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);
});
我在分析函数之前添加了一个等待,并在将promises变量传递到q.allSettled()
中之前添加了一个等待。