2017-07-21 8 views
2

JavaScriptを使用して、その関数の外のPromiseの値にアクセスしようとしています。私は約束をしていないし、私はそれを正しくやっているかわからない。私のコードは以下の通りです:JavaScriptアクセスその関数外の約束

//removed code 

私は基本的に、プロミスから返された値をthen関数内の別の変数に格納しています。私は後の部分でそれらにアクセスしたかったのですが、後の部分でそれらをプリントアウトすると、私は定義されていません。どのようにこれを解決するための任意のアイデア?

私はexamplesが見つかりましたが、動作しません。私のコードのどの部分が間違っているのか分かりません。私は以前にスレッドを開き、それは重複としてマークされ、閉じられた、私は私の質問が十分ではないと思うので、私はここで質問を言い換えている。

ありがとうございました!

+1

プロビジョニングの作成後にp1とp2を直接ログに記録しようとしています。プロミスは非同期であるため、プロミスが解決されるまで値が設定されないため、未定義となっています。 また、promise.allは、約束が解決する値であり、約束自体ではありません。これは動作しません。 Promise.all p1、p2の値をpromiseStoreKeyとpromiseCurrencyKeyで切り替えると、より良い運を得ることができます。 – jas7457

+4

javascriptプログラマには2種類あります。非同期コードを理解している人... –

+0

@ jas7457ありがとうございましたp1とp2をあなたが言及した鍵に変更することで動作します! – guest176969

答えて

1

両方の約束がそれらの値を解決したときにロジックを実行するには、約束オブジェクト上でPromise.all()を使用する必要があります。

Promise.all([promiseCurrencyKey, promiseStoreKey]).then(values => { 
    console.log(values); 
    }); 

JavaScriptは、何か起こるのを待っているコードを持つことを意味するシングルスレッド言語であり、他のすべてをブロックします。さて、しばらく時間がかかるかもしれないものがなければ、実際にはコードを書くことができません。これが約束です。

約束事のロジックがバックグラウンドで処理されており、コードをブロックしていません。 約束によって解決された値を使用するには、値が解決されたときに実行されるthen()メソッドにコールバック関数を設定できます。

解決された値のときにコールバックが実行され、残りのコードが待機しないようにします。

だから、あなたのコードで起こるものを記述すると、以下の通りである:

  1. 実行解決された値がP1
  2. 印刷P1に設定し解決値
  3. ことを背景に、いくつかのロジック - logcでステップ1はまだ完了していないので、その関数のロジックも発生せず、値はまだp1に設定されません

同じようなことが起こりますp2の場合。

さて、あなたはPromise.all()を使用しているとき、あなたは約束を2つの単純な空の変数にそれを実行していないので、結果は2つの空の変数を持つ配列であるオブジェクト...

2番目の例で編集した後、問題は、最初の約束関数内でpromiseBranchKeyを定義したため、この関数のスコープに対してのみ存在し、Promise.all()を呼び出す場所からは外れていないことです。その約束2を考慮

let promiseMerchantKey = new Promise((resolve, reject) => { 
    firebase.database().ref('merchants').orderByChild('merchantName').equalTo('NTUC').once('value', function(snapshot) { 
     let merchantData = snapshot.val(); 
     if (merchantData){ 
      console.log('merchant exists'); 
      resolve(merchantData.key); 
     }else{ 
      // get merchant unique push ID 
      let merchantKey = firebase.database().ref('merchants').push({ 
       address : "NTUC" 
      }).getKey(); 
      resolve(merchantKey); 
     } 
    }); 
}); 

let promiseBranchKey = new Promise((resolve, reject) => { 
    firebase.database().ref('merchants').orderByChild('branchAddress').equalTo('Blk 167').once('value', function(snapshot) { 
     let branchData = snapshot.val(); 
     if (branchData){ 
      console.log('branch exists'); 
      resolve(branchData.key); 
     }else{ 
      // get branch unique push ID 
      promiseMerchantKey.then((merchantKey) => { 
       let branchKey = firebase.database().ref('merchants').child(merchantKey).push({ 
        branchName : 'Marsiling', 
        branchAddress : 'Blk 167' 
       }).getKey(); 
       resolve(branchKey); 
      }); 
     } 
    }); 
}); 

promiseBranchKey.then((branchKey) => { 
    console.log('branchkey' + branchKey); 
    console.log('currencykey' + promiseMerchantKey); 
}); 

は、あなたがそれの内部で使用then()方法を持っており、最初の約束はすでに値を返した場合にのみ発生する約束2の決意を引き起こしすべき約束1によって解決された値に依存します。

約束1がすでに解決されている場合に限り、promise.all()に必要はなく、約束事2を使用して両方の処理が行われたことを示すことができます。

+0

EDITの部分を見てもらえますか?私が現在持っているエラーは、 '変数を見つけることができません:promiseBranchKey'です。 – guest176969

+0

promiseBranchKeyを最初の約束関数の中に定義していますので、この関数のスコープに対してのみ存在し、 'Promise.all () 'を返します。 –

+0

これを解決する方法に関するアイデアはありますか? – guest176969

1

一つのアプローチはまた、単に代わりPromiseコールをネストの.then()又は.catch()呼び出しを連鎖async/await

async function getData() { 
 
    const p1 = await new Promise(resolve => 
 
       setTimeout(resolve, Math.floor(Math.random() * 1200), "p1")); 
 
    console.log(p1); 
 
    const p2 = await new Promise(resolve => 
 
       setTimeout(resolve, Math.floor(Math.random() * 1500), "p2")); 
 
    console.log(p2); 
 
    // do stuff 
 
    // access `p1`, `p2` "later" 
 
    const p3 = await Promise.all([p1, p2]) 
 
      .then(results => 
 
       new Promise(resolve => 
 
        setTimeout(resolve, 1800, [...results, "p3"])) 
 
      ); 
 
       
 
    console.log(p3); 
 
    
 
    return [...p3, "p4"] 
 
} 
 

 
getData() 
 
.then(res => console.log(res))

利用することであろう。 の呼び出しを.then()のいずれかに入れても問題はありません。

重要な点は、実行している手順の特定の時点で期待される結果が何であるかを判断することです。

+0

@EmmaHannah [あなたは約束のポイントを見逃している]を参照してください(https://gist.github.com/domenic/3889970#youre-missing-the-point-of-promises) – guest271314

+0

あなたは私の編集部分を確認できますか?私はそれが働いている。しかし、私の枝は私の店からの約束を必要とし、私はそれを入れ子にしましたが、下のPromise.allは私にpromiseBranchKeyが見つからないというエラーメッセージを伝えています。どのようにこれを修正するための任意のアイデア? – guest176969

+0

エラーが表示されますか?どこ? '.catch()'や '.then()'の2番目のパラメータはJavaScriptのQuestionには現れません。問題は、あなたが '.then()'、 'promiseMerchantKey'、' promiseMerchantKey.then((merchantKey)=> { にチェーンされた '.then()'からの ''返品promiseBranchKey''からの値を ' promiseBranchKey =新しいPromise((resolve、reject)=> {}); promiseMerchantKey}を返す) '。 [promised to chained to promise?](https://stackoverflow.com/q/44439596/2801559) – guest271314

0

ここには、私が最近投稿したすべての実例があります。 Promise skeleton

それはES6であるので、あなたのケースで

return new Promise(function(resolve,reject) { 
//... here you call your firebase and resolve(returnValue) once you get the result 
}); 

var currencyKey; 
return new Promise(function(resolve,reject) { 
     firebase.database().ref('currencies').orderByChild('currencySymbol').equalTo('$').once('value', function(snapshot) { 
       var currencyData = snapshot.val(); 
       if (currencyData){ 
        console.log('currency exists.'); 
       }else{ 
        currencyKey = firebase.database().ref('currencies').push({ 
        currencyName : "Singapore Dollar", 
        currencySymbol : "$" 
        }).getKey(); 

        resolve(currencyKey); 
       } 
       }); 
     }); 
}); 

お知らせ

return new Promise((y,n) => setTimeout(() => y('secondCall'), 800)); 

を置き換える、私はVaRのcurrencyKeyを追加しました。約束の上に。これにより、promiseコードブロックの外部でcurrencyKeyにアクセスできるようになります。

+0

しかし、後の部分でどのようにアクセスしますか? currencyKeyを呼び出すだけで? – guest176969

+0

@EmmaHannah私は上記のコードを修正し、var currencyKeyをPromiseの上に置きました。これにより、残りのコードにアクセスできるようになります。スコープの問題がありました。これで解決するはずです。 –

関連する問題