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

时间:2018-12-07 06:22:22

标签: javascript node.js firebase promise

我有这段代码,其中将用户添加到Firebase数据库,并在用户导入完成后将resolvePromise添加到。在解决方案中,我包括包含所添加用户的数组。添加单个用户时,将填充这些数组。代码如下:

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中。谁能告诉我这是什么问题?

编辑:

我能够解决它,问题是Promise在db.ref.push触发回调之前被解决了,在该回调中,我正在填充数组,因为它是一个异步操作。

1 个答案:

答案 0 :(得分:0)

CertainPerformance said in the comments一样,您的代码仅在假定按顺序调用 push 回调时才有效。由于它们很可能是异步的,因此无法保证回调执行的顺序。 这意味着,如果首先调用最后一个 push 回调,则保证已解决。因此,您应使用Promise.all()等到所有 push < / em>回调已解决,然后处理结果。

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 函数内返回promise以外的其他值将被简单地转发到下一个 then ,就像您返回了Promise.resolve(value)