Массив объектов в JavaScript не возвращается, как ожидалось - PullRequest
2 голосов
/ 13 июня 2019

У меня есть функция, которая возвращает список объектов в 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.

Почему это так, и что я могу сделать, чтобы это исправить?

Ответы [ 2 ]

0 голосов
/ 13 июня 2019

Проблема в том, что ваша функция возвращает переменную до того, как установлено значение. Функция db.serialize будет работать асинхронно (вне обычного потока программы), а оператор return будет выполняться сразу после. Одна вещь, которую вы можете сделать, это использовать async / await вместе с Promise. В этом случае переменная results будет ожидать разрешения обещания, прежде чем перейти к следующей строке.

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

Дополнительное чтение для Async / Await MDN: Asyn / Await

0 голосов
/ 13 июня 2019

Возможная причина, по которой это происходит, из-за асинхронной природы JS, что означает, что все операторы console.log выполняются до успешного выполнения функции listAllEvents(),

Так что мойсоветуем попробовать использовать обещания и выполнять все действия, упомянутые после функции listAllEvents(), только когда эта функция возвращает обещание.

Вы также можете попробовать сделать функцию асинхронной и использовать ожидание, чтобы дождаться ее успешного выполнения.выполнение. (гораздо разумнее будет использовать асинхронный)

Ссылка на функции и использование ASYNC Ссылка на обещания

Также выможно проверить правильность ответа, выполнив console.log(row), когда вы помещаете строки в массив.Вы заметите, что console.log(row) будет выполнен в последний раз, после печати событий и других операторов журнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...