Javascript 承诺链陷入了一个循环
我想调用一个函数,该函数返回一个承诺两次,但当该函数最终永远调用自己时,有时调用外部函数,有时调用内部函数。这是一个有问题的函数,Javascript 承诺链陷入了一个循环,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,我想调用一个函数,该函数返回一个承诺两次,但当该函数最终永远调用自己时,有时调用外部函数,有时调用内部函数。这是一个有问题的函数,retrieveDependency()返回一个承诺 function renderDiffProject(projName, branchName, res, org=undefined){ let newScan; let oldScan; retrieveDependency(projName, branchName, 1, org).then
retrieveDependency()
返回一个承诺
function renderDiffProject(projName, branchName, res, org=undefined){
let newScan;
let oldScan;
retrieveDependency(projName, branchName, 1, org).then(result => {
newScan = result;
console.log("inside retrieve deps");
return retrieveDependency(projName, branchName, 2, org);
})
.then(result => {
oldScan = result;
console.log("successfully got dependencies")
res.render('project', {projname: projName, branch: branchName, proj:JSON.stringify(newScan), oldproj:JSON.stringify(oldScan)})
})
}
这是retrieveDependence()的代码
和数据库。查询定义如下:
class Database {
constructor() {
this.connection = mysql.createConnection({
host: 'azure.com',
user: 'admin-portal-mysql',
password: '2341234#1',
database: 'yatadb'
});
}
query( sql, args ) {
return new Promise( ( resolve, reject ) => {
this.connection.query( sql, args, ( err, rows ) => {
if ( err )
return reject( err );
resolve( rows );
} );
} );
}
我们可以使用async/await简化renderDiffProject:
async function renderDiffProject(projName, branchName, res, org=undefined){
const newScan = await retrieveDependency(projName, branchName, 1, org);
const oldScan = await retrieveDependency(projName, branchName, 2, org);
console.log("successfully got dependencies")
res.render('project', {projname: projName, branch: branchName, proj: JSON.stringify(newScan), oldproj: JSON.stringify(oldScan)})
}
我们还可以简化检索依赖性:
async function retrieveDependency(projname, branch, n, org=undefined) {
// combine both queries
const sql = `
SELECT * FROM branch_scan
WHERE fossa_scan_id = (
SELECT (scanid) FROM foozie
WHERE
project = ${projname}
AND branch = ${branch}
${org ? `AND org = ${org}` : ``}
ORDER BY hist_id DESC
LIMIT ${n - 1}, 1)`;
const records = await database.query(sql);
let dependencies = [];
// map records to promises
return await Promise.all(records.map(record =>
getDepWrapper(record.dep_name_version, dependencies)
));
}
通过简化您的代码,可以更容易地确定您在哪里出错。假设GETEdvRePress实际上解决了,你应该是好的。你应该考虑停止使用<代码>新约定()/<代码>。这是一种反模式的坏习惯。您还可能从async/await
中受益匪浅。我无法从外部判断是什么导致了inifite循环,但至少这两件事应该会大大简化您的代码,并使问题更容易被发现。还注意到您在数据库调用中混合了回调和承诺。绝对值得清理一下!如果有帮助的话,我写了这篇文章:什么是反模式?最好概括为“一些并不罕见的事情”,但“一个相当糟糕的做法”。你可以在谷歌上搜索“Promise constructor anti pattern”,以获取关于这一模式的大量信息。
async function retrieveDependency(projname, branch, n, org=undefined) {
// combine both queries
const sql = `
SELECT * FROM branch_scan
WHERE fossa_scan_id = (
SELECT (scanid) FROM foozie
WHERE
project = ${projname}
AND branch = ${branch}
${org ? `AND org = ${org}` : ``}
ORDER BY hist_id DESC
LIMIT ${n - 1}, 1)`;
const records = await database.query(sql);
let dependencies = [];
// map records to promises
return await Promise.all(records.map(record =>
getDepWrapper(record.dep_name_version, dependencies)
));
}