嵌套多个then函数是错误的做法吗?说“执行此功能,完成后执行此功能”(依此类推)似乎很合逻辑,但是代码看起来很糟糕。
如果有帮助,我最初在firestore的上下文中进行了此查询,先获取用户详细信息,然后获取文档
firebaseApp.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
//If error
}).then(()=>{
firebaseApp.firestore().collection(collectionName).where("associatedID", "==", authID).get().then((snapshot)=>{
snapshot.docs.forEach(doc => {
//Do stuff with data that we've just grabbed
})
}).then(()=>{
//Tell the user in the UI
});
});
有其他选择吗?想到的就是这样
var functionOne = () =>{
console.log("I get called later");
}
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 3000);
});
promise1.then(function(value) {
functionOne();
});
但是即使那样,经过几次.then()之后,它看起来还是可能变得复杂
答案 0 :(得分:2)
从第一个外部.then
返回Promise,然后在第二个外部.then
中使用resolve值,而没有任何嵌套的.then
:
firebaseApp.auth().signInWithEmailAndPassword(email, password)
.then(()=>{
return firebaseApp.firestore().collection(collectionName).where("associatedID", "==", authID).get()
})
.then((snapshot) => {
snapshot.docs.forEach(doc => {
//Do stuff with data that we've just grabbed
});
//Tell the user in the UI
})
.catch((error) => {
// handle errors
});
请确保不要过早catch
-如果链中任何地方出现错误,通常您会希望停止正常执行并直接结束操作(例如,告诉用户有错误) )。
如果您担心代码的可读性,请考虑使用async
/ await
(并为较早的浏览器转换生产代码):
// in an async function:
try {
await firebaseApp.auth().signInWithEmailAndPassword(email, password);
const snapshot = await firebaseApp.firestore().collection(collectionName).where("associatedID", "==", authID).get()
snapshot.docs.forEach(doc => {
//Do stuff with data that we've just grabbed
});
//Tell the user in the UI
} catch(error) {
// handle errors
}
答案 1 :(得分:2)
这取决于您要执行的操作:如果需要访问传递到then
的结果,并且需要访问{{ 1}},嵌套是合理的:
then
不过,通常,您只需要通过从doSomething()
.then(result1 => {
return doSomethingElse()
.then(result2 => {
return result1 + result2;
});
})
.then(combinedResult => {
// Use `combinedResult`...
})
.catch(/*...*/);
处理程序返回后续操作中的promise,就可以在链中传递单个值:
then
这样做可以将创建的承诺doSomething()
.then(result => {
return doSomethingElse(result);
})
.then(lastResult => {
// `lastResult` is the fulfillment value from `doSomethingElse(result)`
})
.catch(/*...*/);
解析为查询中then
返回的承诺。 (“ 解决承诺 某事”表示您已根据解决的事情做出了承诺的和解。如果您将其解决为另一个承诺,其解决取决于其他承诺的解决。)
看看您的Firebase示例,我可能无需嵌套即可:
get()
答案 2 :(得分:1)
您应该链接promise,并且还可以命名函数,恕我直言,IMHO可以显着提高可读性。考虑这样的事情
const signIn = () => firebaseApp.auth().signInWithEmailAndPassword(email, password);
const onSigninError = (err) => // error handling logic here
const getCollection = () => firebaseApp.firestore().collection(collectionName).where("associatedID", "==", authID)
.get();
const processSnapshot = (snapshot) => snapshot.doc.forEach(// do stuff here
const displayMessage = () => // do stuff here
signIn()
.catch(onSigninError)
.then(getCollection)
.then(processSnapshot)
.then(displayMessage);