Обратный вызов выполнен слишком рано - PullRequest
0 голосов
/ 12 ноября 2018

Я борюсь с проблемой, которую не могу обойти.

Я использую NodeJS для запроса данных от Rest API. Для этой программы я сначала извлекаю массив данных, затем запрашиваю некоторые детали из другой конечной точки на основе идентификатора из первого массива.

Я использую цикл foreach внутри первого вызова функции с обратным вызовом, а затем другой вызов функции внутри цикла foreach для получения подробностей.

Что я испытываю, так это то, что вторая функция выполняет обратный вызов до получения ответа.

Мне удалось воспроизвести проблему с помощью следующего примера кода:

console.log('Program start')

// Executing program
getFirstname(function(person) {

    person.forEach(firstname => {

        getSurname(firstname.id, function(lastname) {
            console.log(`${firstname.value} ${lastname}`)
        });

    });
})

// Emulating REST API´s
function getFirstname(callback) {

    console.log('Returning list of firstnames')

    let data = [
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
        {id: 0, value: 'John'},
        {id: 2, value: 'Andy'},
        {id: 3, value: 'Jimmy'},
        {id: 4, value: 'Alex'},
    ]

    callback(data);
}

function getSurname(id, callback) {

    console.log(`Querying for lastname id ${id}`)

    let data = [
        'Andersen',
        'Johsen',
        'Falon',
        'Alexander',
    ]

    setTimeout(() => {
        callback(data[id]);
    }, 2000);
}

Вот результат программы:

Program start
Returning list of firstnames
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
Querying for lastname id 0
Querying for lastname id 2
Querying for lastname id 3
Querying for lastname id 4
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined
John Andersen
Andy Falon
Jimmy Alexander
Alex undefined

Как видите, есть несколько записей со значением undefined. Также я добавил setTimeout, чтобы эмулировать, что каждый вызов покоя занимает несколько секунд. Случается так, что все запросы запускаются мгновенно, затем идет 2 секунды, прежде чем все ответы возвращаются одновременно.

Я ожидал бы, что это будет ждать каждого второго вызова rest и затем возвращать результат.

Как я могу решить эту проблему?

С наилучшими пожеланиями, Кристиан

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

В ваших обратных вызовах нет ничего плохого.Данные, однако, неверны.См. Ниже:

function getSurname(id, callback) {

    console.log(`Querying for lastname id ${id}`)

    let data = [
        'Andersen',
        'Johsen',
        'Falon',
        'Alexander',
    ]

    setTimeout(() => {
        callback(data[id]);
    }, 2000);
}

Каждый раз, когда вызывается Alex, вы передаете идентификатор 4 для использования в массиве data.Помните, что массивы 0 основаны, поэтому data[4] = undefined ...

0 голосов
/ 12 ноября 2018

Причина, по которой у вас есть undefined, заключается в том, что ваш массив data имеет длину 4 (индексы идут от 0 до 3 ), а диапазон id от 0 до * 1007. * 4 . Это означает, что когда вы ссылаетесь на data[4], вы получаете undefined.

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