Node.js向SQL Server插入对象数组属性遇Id_Oficina未定义如何解决
问题原因
你遇到的属性未定义错误是多个逻辑错误共同导致的,按优先级排序如下:
第一:for循环遍历条件写反
你当前写的遍历逻辑是for (var m = 0; m >= lstValid.length; m++),判断条件完全错误,正常遍历数组的判断条件应为m < lstValid.length。
按照你现在的写法,只要数组长度≥0(所有数组默认满足),第一次循环m=0就会触发执行,如果此时lstValid是空数组,lstValid[0]本身就是undefined,读取Id_Oficina属性自然抛出对应错误。第二:异步逻辑没有等待,数组未完成填充就开始操作
calcWeather是异步函数,内部调用的openweathermap接口请求也都是异步任务,你在executeStatement中调用calcWeather()后立刻遍历lstValid,此时所有接口请求都还未返回结果,lstValid还没有被填充任何元素,绝大多数时候都是空数组,刚好触发第一个错误的遍历逻辑。第三:你尝试的修复写法逻辑错误
你向lstValid数组中push的就是myObject对象本身,所以lstValid[m]就是你要读取的目标对象,不需要额外加.myObject层级,这个错误写法只会读取不存在的属性,依然会报错。额外问题:
requestCompleted监听位置错误
你将该监听写在了for循环外部,但request变量是在for循环内部定义的,外部作用域访问不到该变量,这部分逻辑也不会正常生效。
修复方案
第一步:改造calcWeather,保证所有异步请求完成后再返回
async function calcWeather() { const info = await fetch("../json/data.json").then(res => res.json()); // 收集所有fetch请求的Promise,保证全部执行完成再返回 const fetchPromises = []; for (var i in info) { const _idOficina = info[i][0].IdOficina; const lat = info[i][0].latjson; const long = info[i][0].lonjson; const base = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${long}&appid=${api_key}&units=metric&lang=sp`; // 将每个fetch的Promise放到数组中统一等待 fetchPromises.push( fetch(base) .then(res => res.json()) .then(data => { const myObject = { Id_Oficina: _idOficina, Humedad: data.main.humidity, Nubes: data.clouds.all, Sensacion: data.main.feels_like, Temperatura: data.main.temp, Descripcion: data.weather[0].description, }; if (myObject.Temperatura < 99) { lstValid.push(myObject); } }) ); } // 等待所有天气接口请求完成,保证lstValid填充完毕 await Promise.all(fetchPromises); }
第二步:改造executeStatement,等待异步逻辑完成后再遍历,修正循环条件
import { Request } from "tedious"; import { TYPES } from "tedious"; // 改为async函数,支持await等待异步任务 async function executeStatement() { // 等待calcWeather所有逻辑执行完成,lstValid已经填充完毕 await calcWeather(); // 修正循环条件,只有m小于数组长度时才执行 for (var m = 0; m < lstValid.length; m++) { const request = new Request( "EXEC USP_BI_CSL_insert_reg_RegistroTemperaturaXidOdicina @IdOficina, @Humedad, @Nubes, @Sensacion, @Temperatura, @Descripcion", function (err) { if (err) { console.log("Couldn't insert data: " + err); } } ); request.addParameter("IdOficina", TYPES.SmallInt, lstValid[m].Id_Oficina); request.addParameter("Humedad", TYPES.SmallInt, lstValid[m].Humedad); request.addParameter("Nubes", TYPES.SmallInt, lstValid[m].Nubes); request.addParameter("Sensacion", TYPES.Float, lstValid[m].Sensacion); request.addParameter("Temperatura", TYPES.Float, lstValid[m].Temperatura); request.addParameter("Descripcion", TYPES.VarChar, lstValid[m].Descripcion); request.on("row", function (columns) { columns.forEach(function (column) { if (column.value === null) { console.log("NULL"); } else { console.log("Product id of inserted item is " + column.value); } }); }); // 监听requestCompleted移动到request作用域内,所有请求完成后关闭连接 if (m === lstValid.length - 1) { request.on("requestCompleted", function () { connection.close(); }); } connection.execSql(request); } }
内容的提问来源于stack exchange,提问作者Martín JF
相关产品推荐
相关产品推荐

