Mengapa Firebase Kehilangan Rujukan di luar Fungsi once()?
Firebase menggunakan pemprosesan tak segerak, yang bermaksud mengambil data daripada pangkalan data tidak dilaksanakan secara berurutan. Akibatnya, percubaan untuk mengakses senarai pengguna serta-merta selepas melampirkan pendengar dalam fungsi userService.getUsers tidak akan menghasilkan output yang diingini.
Coretan kod yang disediakan:
.service('userService', [function() { this.getUsers = function() { var users; var userList; var ref = firebase.database().ref('/users/'); ref.once('value').then(function(snapshot) { users = snapshot.val(); for(var key in users) { users[key].id = key; // do some other stuff } console.log(users); // outputs all users }).then(function(){ userList = users; console.log(userList); // outputs all users },(function(error){ alert('error: ' + error); }); console.log(userList); // outputs 'undefined' } }]);
Menunjukkan ini tingkah laku tak segerak. Output konsol ialah:
before attaching listener after attaching listener got value
Untuk menyelesaikan isu ini, anda mempunyai tiga pilihan:
1. Gunakan Senarai Pengguna dalam Panggilan Balik:
Alihkan semua kod yang diperlukan yang beroperasi pada senarai pengguna ke dalam panggilan balik:
ref.once('value', function(snapshot) { users = snapshot.val(); for(var key in users) { users[key].id = key; } console.log(users); // outputs all users })
2. Kembalikan Janji:
Kembalikan janji daripada userService.getUsers dan rangkaian operasi berikutnya kepadanya:
this.getUsers = function() { var ref = firebase.database().ref('/users/'); return ref.once('value').then(function(snapshot) { users = snapshot.val(); for(var key in users) { users[key].id = key; // do some other stuff } return(users); }).catch(function(error){ alert('error: ' + error); }); }
Anda kemudian boleh menggunakan janji untuk meneruskan pemprosesan sebaik sahaja data dimuatkan :
userService.getUsers().then(function(userList) { console.log(userList); })
3. Gunakan Async dan Await (Memerlukan Sokongan ES2017):
Tandai fungsi getUsers sebagai async dan gunakan kata kunci await untuk menjeda pelaksanaan sehingga janji diselesaikan:
this.getUsers = async function() { var ref = firebase.database().ref('/users/'); const snapshot = await ref.once('value'); const users = snapshot.val(); for(var key in users) { users[key].id = key; // do some other stuff } return users; }
Anda boleh kini gunakan fungsi seperti:
async function getAndLogUsers() { const userList = await userService.getUsers(); console.log(userList); }
Dengan memahami pelaksanaan tak segerak dalam Firebase, anda boleh mengakses data daripada pangkalan data anda dengan berkesan dan mengelakkan kemungkinan rujukan yang tidak ditentukan.
Atas ialah kandungan terperinci Mengapa Rujukan Firebase Saya Menjadi Tidak Ditakrifkan di Luar Fungsi `sekali()`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!