Javascript resolve()返回使用Array.push()填充的空数组

Javascript resolve()返回使用Array.push()填充的空数组,javascript,node.js,firebase,promise,Javascript,Node.js,Firebase,Promise,我有这样一段代码,其中我将用户添加到Firebase DB,并在用户导入完成时解析Promise。在解析中,我包含了包含已添加用户的数组。这些数组在添加单个用户时填充。代码如下: return new Promise((resolve, reject) => { let usersAdded = []; users.map((user, index) => { db.ref('/users').push(user, err => {

我有这样一段代码,其中我将用户添加到Firebase DB,并在用户导入完成时解析
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触发回调之前,承诺就已经解决了,在该回调中,我正在填充数组,因为这是一个异步操作。

就像您的代码一样,只在按顺序调用推送回调的情况下才起作用。因为它们很可能是异步的,所以回调执行的顺序不能保证这意味着如果先调用最后一次推送回调,您承诺已解决。因此,您应该使用等待,直到所有推送回调解决,然后处理结果

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);
});

在then函数中返回承诺以外的值将被转发到下一个then函数,就像返回了
承诺一样。解析(值)

是否应该调用
承诺。如果要迭代所有
用户
,则只能解析承诺一次。您的代码似乎在尝试解决承诺,其次数与
users
中的元素次数相同。我不确定你在这里的意图。嘿,@DougStevenson很高兴你回答了你的一个超级粉丝,你可以看到我有一个
if
语句,其中条件只有在循环在最后一次迭代时才是真的。@CertainPerformance这个承诺在一个函数内,这个函数由另一个函数调用。因此,当它在循环的最后一次迭代中被解析时,它应该返回
usersAdded
数组,该数组将使用
res()发送给用户。send()
只有在异步
db.ref…push
串行执行时,您所做的工作才会起作用-否则,无法保证调用的最后一项
push
将是最后一个要完成的异步操作。最好使用
Promise.all
,虽然我不确定
usersAdded
结果为何为空,但我希望它至少包含一项(除非出现错误,在这种情况下,您可能希望
拒绝
-同时避免显式Promise构造反模式)