Promise.resolve () возвращает пустые массивы, которые были заполнены с помощью Array.push () - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть этот код, в который я добавляю пользователей в Firebase DB, и resolve Promise, когда пользовательский импорт завершен.В разрешении я включаю массивы, которые содержат добавленных пользователей.Эти массивы заполняются при добавлении одного пользователя.Код ниже:

return new Promise((resolve, reject) => {
    let usersAdded = [];
    users.map((user, index) => {
        db.ref('/users').push(user, err => {
            if(!err) {
                usersAdded.push(user)
                console.log(`Array at iteration ${index}: ${usersAdded}`)
            }
            if(index == users.length-1){
              resolve({status: true, usersAdded})
            }
        })
    })
})

Вывод на консоль:

Array at iteration 0: [{name: nadir, email: iamnadir10@yahoo.com, creditCard: true}]
Array at iteration 1: [{name: nadir, email: iamnadir10@yahoo.com, creditCard: true}, {name: arslan, email: arslan346@yahoo.com, creditCard: true}]
Array at iteration 2: [{name: nadir, email: iamnadir10@yahoo.com, creditCard: true}, {name: arslan, email: arslan346@yahoo.com, creditCard: true}, {name: farhan, email: farhan1992@gmail.com, creditCard: true}]

Хотя, когда я вижу ответ на .then(user), он возвращает пустой массив (usersAdded).Пользователи также добавляются в Firebase.Может кто-нибудь сказать мне, в чем здесь проблема?

Редактировать:

Я смог ее решить, проблема была в том, что Обещание было решено до того, как db.ref.push запустил обратный вызов,в этом обратном вызове я заполнял массив, поскольку это была асинхронная операция.

1 Ответ

0 голосов
/ 07 декабря 2018

Как CertainPerformance сказал в комментариях Ваш код работает только при условии, что обратные вызовы push вызываются по порядку.Поскольку они, скорее всего, асинхронные, порядок выполнения обратного вызова не гарантируется. Это означает, что если последний обратный вызов push вызывается первым, который вы обещаете, уже разрешается. По этой причине вам следует использовать Promise.all () подождать, пока все обратные вызовы push не будут разрешены, а затем обработать результаты.

return Promise.all(users.map(user => {
    return new Promise(resolve => db.ref('/users').push(user, resolve));
}))
.then(pushResults => { // all push callbacks are resolved
    return pushResults
        .map((error, index) => error ? null : users[index])
        .filter(Boolean);
});

Однако вы можете вызвать reject , если ни один из пользователей не успешно сохранил.Это усложняет код, но вы можете использовать catch в возвращенном обещании, если ни один пользователь не был сохранен.

// return a resolved promise if the users array is empty
if (!users.length) return Promise.resolve(users);

// handle a non-empty users array
return Promise.all(users.map(user => {
    return new Promise(resolve => db.ref('/users').push(user, resolve));
}))
.then(pushResults => {
    // all users had errors
    if (pushResults.every(Boolean)) 
        return Promise.reject(pushResults);

    // one or multiple users had no errors
    return pushResults
        .map((error, index) => error ? null : users[index])
        .filter(Boolean);
});

Возвращение значения, отличного от обещания, внутри тогда функция будет просто перенаправлена ​​на следующий , затем , как если бы вы вернули Promise.resolve(value).

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