'的承诺'返回空数组

时间:2017-12-01 15:06:56

标签: node.js promise

我正在尝试返回存储在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()时,数组变空。

感谢您的帮助。

3 个答案:

答案 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;
  }