我有一个函数,该函数返回Javascript中的对象列表,并且我正在从另一个函数中调用该函数,并尝试使用其中的某些值,但是每当我尝试访问所述值时,它们都会返回未定义状态。
这是我生成列表的函数-想法是,如果不存在,它将创建一个sqlite3数据库,并返回包含每个事件的数组。
function listAllEvents() {
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('schedule.db');
const selectionArray = [];
db.serialize(() => {
db.run(`
CREATE TABLE IF NOT EXISTS todo (
name text,
date text,
id text primary key
)
`);
db.all('SELECT * FROM todo ORDER BY date', [], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
selectionArray.push(row);
});
});
});
return selectionArray;
}
我从另一个函数中调用了该函数,但是当我尝试从数组中访问值时,它们似乎无法正常工作,我无法弄清楚。
function displayUpcomingEvents() {
const events = listAllEvents();
// console.log(events); <-- This line here! In the console, it correctly states the length of the array
// console.log(events.length) <-- This line, however, returns 0. Why?
// console.log(events[0]) <-- This doesn't work either, it just returns "undefined".
for (let i = 0; i < events.length; i += 1) {
$('#upcomingEvents').after('<li>asdf</li>');
}
}
例如,如果我要通过控制台在数据库中创建两个事件,
events is an Array(2) with indices
- 0: {name: "my_event", date: "2019-06-04", id: "c017c392d446d4b2"}
- 1: {name: "my_event_2", date: "2019-06-04", id: "6d655ac8dd02e3fd"},
events.length returns 0,
and events[0] returns undefined.
这是为什么,我该怎么解决?
答案 0 :(得分:0)
发生这种情况的可能原因是由于JS的异步特性,这意味着在成功执行console.log
函数之前,所有listAllEvents()
语句都已被执行,
所以我的建议是尝试使用Promise,仅在该函数返回Promise时,执行listAllEvents()
函数之后提到的所有操作。
您还可以尝试使函数异步,并使用await等待其成功执行。 (更明智的选择将是使用异步)
Link to ASYNC Functions and Usage Link to Promises
您还可以通过执行console.log(row)
来检查答案的有效性,其中将行推入数组。您将观察到console.log(row)
将在打印事件和其他日志语句之后最后执行。
答案 1 :(得分:0)
问题在于您的函数在设置值之前返回了变量。 db.serialize
函数将异步运行(在程序的正常流程之外),而return语句将在此之后立即运行。您可以做的一件事是将异步/等待与Promise
结合使用。在这种情况下,变量results
将在继续下一行之前等待promise被解决。
async function listAllEvents() {
const selectionArray = [];
let promise = new Promise( function (resolve, reject) {
db.serialize(() => {
db.run(
CREATE TABLE IF NOT EXISTS todo (
name text,
date text,
id text primary key
)
);
db.all('SELECT * FROM todo ORDER BY date', [], (err, rows) => {
if (err) {
// add code here to reject promise
throw err;
}
rows.forEach((row) => {
selectionArray.push(row);
});
resolve(selectionArray);// resolve the promise
});
});
});
let results = await promise;
return results;
};
async function displayUpcomingEvents() {
const events = await listAllEvents();
// console.log(events); <-- This line here! In the console, it correctly states the length of the array
// console.log(events.length) <-- This line, however, returns 0. Why?
// console.log(events[0]) <-- This doesn't work either, it just returns "undefined".
for (let i = 0; i < events.length; i += 1) {
$('#upcomingEvents').after('<li>asdf</li>');
}
}
请注意,displayUpcomingEvents
函数也将需要异步,否则您将无法使用await关键字。
Promise关键字MDN: Promise的其他阅读内容
异步/等待MDN: Asyn/Await的其他阅读内容