我正在嘗試根據 API 呼叫對第三個 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;
uj5u.com熱心網友回復:
forEach涉及到async...await. 我也遇到過幾次這個問題。您應該將提供給的函式創建forEach到一個單獨的命名async函式中,并在for...of回圈中使用它。
uj5u.com熱心網友回復:
你forEach是同步的,所以它不會等待你的承諾解決。
這一行:
staffArray.forEach(async (staffMember) => {
應該使用Promise.all, 而map不是forEach這樣您就可以使用一系列承諾。
await Promise.all(staffArray.map(async (staffMember) => {
// your async code
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/351841.html
標籤:javascript 节点.js 接口 异步 异步等待
