我正在尝试返回存储在Firebase中的令牌数组,我正在使用'承诺'。
while(number>0)
{
sum+=number%TEN;
number=number/TEN;
}
这就是' getToken'来自"助手的方法"模块。
function getUsersTokens() {
let dbRef = db.ref('/system/users');
let result = new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
let tokens = [];
snap.forEach(child => {
if(child.Status != "occupied"){
helper.getToken(child.key,db).then(function(token){
tokens.push(token);
});
}
});
resolve(tokens);
}, (err) => {
reject(err);
});
});
return result;
}
问题是每次我将令牌推入数组时它都可以正常工作,但是当退出getUsersTokens()时,数组变空。
感谢您的帮助。
答案 0 :(得分:2)
问题是您的result
承诺过早解决,因为helper.getToken()
是非阻止的,因此您的forEach
将在所有getToken()
来电之前完成已完成将其令牌推入tokens
。
为了使事情变得更容易,您可以将result
承诺分成两个承诺。第一个承诺将负责获得snap
。第二个承诺将负责迭代snap
以生成一系列令牌:
function getUsersTokens() {
let dbRef = db.ref('/system/users');
let result = new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
resolve(snap);
}, (err) => {
reject(err);
});
});
return result.then(snap => {
let prommiseArr = [];
snap.forEach(child => {
if(child.Status != "occupied"){
let p = helper.getToken(child.key,db);
promiseArr.push(p);
}
});
return Promise.all(promiseArr); // resolves to array of tokens
});
}
Promise.all
接受一系列承诺,并在所有承诺也已解决时解决。 getUsersToken
返回的承诺最终将包含一系列令牌,因为promiseArr
的每个承诺都会解析为令牌。
答案 1 :(得分:1)
这是因为在getToken()
解析之前,使用令牌数组解析了promise。您会看到一个空数组,因为您的处理程序在令牌到达之前运行。
你需要在解决之前等待。像这样:
function getUsersTokens() {
let dbRef = db.ref('/system/users');
return new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
const tokensPromise = snap
.filter(child => child.Status !== "occupied")
.map(child => helper.getToken(child.key, db));
resolve(Promise.all(tokensPromise));
});
});
}

答案 2 :(得分:0)
Promise.all正如@AndréWerlang和@Christian Santos所指出的那样,这里的完美是一个使用reduce方式的例子
function getUsersTokens() {
let dbRef = db.ref('/system/users');
let result = new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
snap.reduce((chain, child) => {
return chain.then(array => {
return helper.getToken(child.key,db).then(function(token){
return array.push(token);
});
});
}, Promise.resolve([])).then(tokens=>{
resolve(tokens);
});
}, (err) => {
reject(err);
});
});
return result;
}