2017-12-20 11 views
0

私はJavaScriptを備えたFirebaseを初めて使いました。私は、取得したデータの出力で約束を返すことができます。しかし、私は本当に、次の場合にはそれを見抜くことはできません。このような場合に約束を返すには?

filterUsersAndCalculateMatches = (userProfile, userID, potentialMatches, maxDistanceToSearchForMatches) => { 
    const TOTAL_SCORE = 100; 
    var matches = {}; // Matches to be stored in the database 
    potentialMatches.forEach(user => { 
    if (user.val() !== userID) { 

      databaseRef.child(`users/${user.val()}/profile`).once("value", (snapshot) => { 
      const matchScore = calculateMatchScore(userProfile, snapshot.val(), maxDistanceToSearchForMatches); 
      //console.log("final score is " + matchScore); 
      if (matchScore) { 
       const match = { 
        compatibility: matchScore/TOTAL_SCORE, 
        distance: distance, 
        profile: snapshot.val() 
       } 
       matches[user.val()] = match; 
      } 
      }); 
    } 
    }); 
}; 

私は、ユーザーのIDのを反復処理し、いくつかの計算を行うと、オブジェクトへの自分のプロファイルと一緒に結果を追加して自分のプロファイルにアクセスしています。

すべてのユーザーが終了した後、約束オブジェクトを返す方法はありますか?

+0

を処理していませんでした注意あなたが達成しようとしていると何をしようとしたものに多くのコンテキストを与えることができます。 –

答えて

1

.once()は約束を返します。 Promise.all()を使用できます。 Promise.all()は引数として約束事の配列を取得し、渡された約束がすべて解決されたときに解決する約束を返します。あなたは、リスト内の約束の一つが拒否された場合でも解決したい場合があります

filterUsersAndCalculateMatches = (userProfile, userID, potentialMatches, maxDistanceToSearchForMatches) => { 
    var matches = {}; // Matches to be stored in the database 
    const promisesList = []; 
    potentialMatches.forEach(user => { 
    if (user.val() !== userID) { 
     // save a reference to the promise 
     const dataPromise = databaseRef.child(`users/${user.val()}/profile`).once("value", (snapshot) => { 
      // ... 
      }); 
     // push the promise in the promise list 
     promiseList.push(dataPromise); 
    } 
    }); 

    return Promise.all(promisesList).then(() => Promise.resolve(matches)); 
}; 

: 変更されたコードは次のようになります。 拒否された約束を処理することができます。

promiseList.push(
    // have to handle the reject 
    dataPromise 
    .then(data => data) 
    // returns a resolved promise with { error } object. 
    // doing this Promise.all() will always resolve even if some of them are rejected. 
    .catch(error => { 
     return { error: error }; 
    }) 
); 
+0

あなたの答えをありがとう。私はそれを試して、私は返された約束を記録するとき私は保留中のものを得る...どのように試合を抽出することができますか? –

+0

解決されない約束のハンドルを追加することができます。 Promise.all()は、すべての約束が解決された場合にのみ解決します。私は答えを更新します。 – bogdanpetru

0

matchesオブジェクトで解決される約束事は、プロファイルの繰り返しが完了したときに作成できます。私は、エラー

filterUsersAndCalculateMatches = (userProfile, userID, potentialMatches, maxDistanceToSearchForMatches) => { 
 
    //Return a new promise 
 
    return new Promise((resolve, reject) => { 
 
    const TOTAL_SCORE = 100; 
 
    var matches = {}; // Matches to be stored in the database 
 
    var promises = []; // create an array for promises during iteration over profiles 
 
    potentialMatches.forEach(user => { 
 
     if (user.val() !== userID) { 
 
     // Save promise in var p 
 
     var p = databaseRef.child(`users/${user.val()}/profile`).once("value").then((snapshot) => { 
 
      const matchScore = calculateMatchScore(userProfile, snapshot.val(), maxDistanceToSearchForMatches); 
 
      //console.log("final score is " + matchScore); 
 
      if (matchScore) { 
 
      const match = { 
 
       compatibility: matchScore/TOTAL_SCORE, 
 
       distance: distance, 
 
       profile: snapshot.val() 
 
      } 
 
      matches[user.val()] = match; 
 
      } 
 
     }); 
 
     promises.push(p); 
 
     } 
 
    }); 
 

 
    Promise.all(promises).then(resolve.bind(resolve, matches)); 
 
    }); 
 
};

+0

あなたの答えをありがとう。私はそれを試して、私は返された約束を記録するとき私は保留中のものを得る...どのように試合を抽出することができますか? –

+1

返された 'promise'をすぐにログに記録すると、async関数が実行されていないため、' pending'になります。マッチを取得するには、 'then'関数を使ってマッチを取得する必要があります。そして、非同期操作が完了すると 'then'関数が実行されます。たとえば、次のように ' filterUsersAndCalculateMatches(引数1、ARG2 ...)それは...のためにありがとうございましたん .then((マッチ)=> { にconsole.log(マッチ) }) ' – DaProgrammer

+0

あなたの助け。私はあなたのコメントを評価したが、彼が最初に答えたので、私はbogdanpetruに正しい答えを与えなければならない。再度、感謝します。 –

関連する問題