JavaScript访问在then函数之外的Promise

时间:2017-07-21 02:06:52

标签: javascript promise global-variables

我正在尝试使用JavaScript访问then函数之外的Promise中的值。我是Promise的新手,我不确定我是否正确地做到了。这是我的代码:

//removed code

基本上我将Promise返回的值存储到then函数中的一个单独变量中。我想在后面的部分访问它们,但是当我在后面的部分打印出来时,它会返回我的未定义。关于如何解决这个问题的任何想法?

我找到了examples并跟着它们,但它不起作用。我不确定我的代码的哪一部分是错的。我之前打开了一个帖子,它被标记为重复并关闭,我想我的查询不够清楚,因此我在这里重新提出这个问题。

先谢谢!

3 个答案:

答案 0 :(得分:1)

这是我最近发布的一个工作承诺。 Promise skeleton

它在ES6中,所以替换

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

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);
                }
              });
        });
});

注意,我已经添加了var currencyKey;承诺之上。这使得currencyKey可以在Promise代码块之外访问。

答案 1 :(得分:1)

为了在两个promises都解决了它们的值时执行逻辑,你应该在promises对象上使用Promise.all()

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

JavaScript是一种单线程语言,这意味着让代码等待发生的事情将阻止其他一切。现在,我们无法在没有有时可能需要一段时间的事情的情况下编写代码,这就是Promises的用途。

承诺中的逻辑正在后台处理而不是阻止代码。 为了使用promise所解析的值,您可以将回调函数设置为then()方法,该方法将在解析值时执行。

当解析的值没有使代码的其余部分等待时执行回调。

所以描述你的代码会发生什么:

  1. 在后台运行一些解析值的逻辑
  2. 当值已解决时将其设置为p1
  3. print p1 - 步骤1中的logc尚未完成,这意味着then函数中的逻辑也没有发生,且值仍未设置为p1
  4. p2也是如此。

    现在,当您使用Promise.all()时,您正在两个简单的空变量上执行它,而不是在promises对象上执行它,因此结果是带有两个空变量的数组...

    在编辑之后的第二个例子中,问题是你在第一个promise函数中定义了promiseBranchKey,所以它只存在于这个函数的范围内,而不是你调用它的地方{{1} }。

    Promise.all()

    考虑到promise 2取决于promise 1解析的值,你应该在其中使用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); }); 方法,并且只有当第一个promise已经返回值时才会导致promise 2的解析。

    因为只有在承诺1已经解决的情况下才能解决承诺2,所以then()中没有必要,我们可以在承诺2上使用它来指示何时处理它们。

答案 2 :(得分:0)

一种方法是利用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().catch()来代替嵌套Promise来电;虽然嵌套Promise .then()调用也不应该存在问题。

重要的一点是确定您正在执行的程序中给定点的预期结果。