【发布时间】:2021-12-19 06:59:44
【问题描述】:
我正在尝试根据 API 调用对 3rd aprty 的响应创建一系列“INSERT INTO”查询。
API 响应被分解为不同的页面,我循环浏览数据,然后循环浏览页面,尝试更新每条数据的字符串。
正在到达响应的所有页面,并且正在将数据添加到总字符串中,但正在发生的情况是返回发生得太早 - 也就是说,除了最后一页之外的所有数据都被返回。我不知道为什么返回对象bulkInsertString 被返回得太早了一页。关注的函数是getBulkInsert 函数...我认为它与while 循环中的条件有关,一旦到达最后一页就停止运行。最后一页页面上的数据肯定已经到达,因为它正在记录在console.log('string added',forename,surname)...中,但是这样做太晚了。我想知道我是否在某处错过了“等待”。谁能看到我必须如何调整我的代码以确保我返回所有数据,包括最后一页?我以为既然 return 语句是在 while 循环之后,那么一旦 while 循环完成它就会返回?
当服务器开始运行时,'syncStaffRoll'函数被调用:
const axios = require("axios");
const generateString = require("./queryBuilders/CreateInsertInto");
const sql = require("mssql");
const getBulkInsert = async (schoolId, myDate) => {
var queryStart = "";
var bulkInsertString = "";
var lastPage = false;
var endPoint = `***`;
var i = 1;
while (!lastPage) {
console.log(`currently on element ${i} of response`);
const config = {
method: "get",
url: endPoint,
headers: {
Authorization: "Bearer " + process.env.TOKEN,
},
};
await axios(config).then((response) => {
const staffArray = response.data.data;
console.log(
`${staffArray.length} staff objects received in this API call`
);
lastPage = !response.data.meta.pagination.more;
endPoint = response.data.meta.pagination.next;
if (lastPage) {
console.log("this is the final page");
}
staffArray.forEach(async (staffMember) => {
try {
const { id, surname, forename, contact_details } = staffMember;
const { data } = contact_details;
const { emails } = data;
const { primary, work } = emails;
const getEmail = () => {
if (work) {
return work;
} else {
return primary;
}
};
var nextString = await generateString("SyncStaff", "UpdatedAt", {
StaffId: id,
Surname: surname.replace(/'/g, '"'),
FirstName: forename.replace(/'/g, '"'),
StaffEmail: getEmail(),
StaffRole: "Staff",
UpdatedAt: myDate,
});
bulkInsertString = bulkInsertString + nextString;
console.log("string added", forename, surname);
// console.log(bulkInsertString);
} catch (err) {
console.log(`error in staffMember ${staffMember.id}`, err);
// console.log(err);
}
});
});
i += 1;
}
return bulkInsertString;
};
const getQuery = async (schoolId, myDate) => {
const queryStart = `
BEGIN TRANSACTION [Tran1]\n
BEGIN TRY\n
`;
const queryEnd = `
COMMIT TRANSACTION [Tran1]\n
END TRY\n
BEGIN CATCH \n
ROLLBACK TRANSACTION [Tran1]\n
END CATCH
`;
const bulkInsertString = await getBulkInsert(schoolId, myDate);
const removalString = `DELETE FROM SyncStaff where UpdatedAt != '${myDate}'`;
const queryString = queryStart + bulkInsertString + removalString + queryEnd;
return queryString;
};
const performQuery = async (query) => {
console.log("trying to perform query", query);
const sqlConfig = {
user: process.env.DB_USER,
password: process.env.DB_PWD,
database: process.env.DB_NAME,
server: process.env.DB_SERVER,
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000,
},
options: {
encrypt: true, // for azure
trustServerCertificate: false, // change to true for local dev / self-signed certs
},
};
const runQuery = async () => {
try {
// make sure that any items are correctly URL encoded in the connection string
await sql.connect(sqlConfig);
const result = await sql.query(query);
return "Query Completed";
} catch (err) {
console.log(err);
return err;
}
};
const result = await runQuery();
return result;
};
const syncStaffRoll = async (schoolId) => {
const d = new Date();
const myDate = d.toString("en-AU");
//generates the query to be used
const query = await getQuery(schoolId, myDate);
console.log(query);
// const queryResult = await performQuery(query);
// console.log(queryResult);
};
module.exports = syncStaffRoll;
【问题讨论】:
-
你为什么要结合
await和.then()?使用其中之一,而不是两者。 -
你不应该再使用
.forEach了。请改用for( of )。 -
generateString的定义是什么?
标签: javascript node.js api asynchronous async-await