我正在尝试使用JavaScript访问then函数之外的Promise中的值。我是Promise的新手,我不确定我是否正确地做到了。这是我的代码:
//removed code
基本上我将Promise返回的值存储到then函数中的一个单独变量中。我想在后面的部分访问它们,但是当我在后面的部分打印出来时,它会返回我的未定义。关于如何解决这个问题的任何想法?
我找到了examples并跟着它们,但它不起作用。我不确定我的代码的哪一部分是错的。我之前打开了一个帖子,它被标记为重复并关闭,我想我的查询不够清楚,因此我在这里重新提出这个问题。
先谢谢!
答案 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()
方法,该方法将在解析值时执行。
当解析的值没有使代码的其余部分等待时执行回调。
所以描述你的代码会发生什么:
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()
调用也不应该存在问题。
重要的一点是确定您正在执行的程序中给定点的预期结果。