我正在撰寫一個歌詞應用程式,它將歌曲書和該書中的歌曲保存到 SQL lite 資料庫。我正在映射一系列書籍并呼叫 API 來保存書中的歌曲。我希望 saveBook() 函式在轉到 saveBookSong() 函式之前完全完成。我嘗試過異步等待,但它不起作用。任何幫助將不勝感激,謝謝,山姆
useEffect( () => {
Books.map ((book) =>{
saveBook(book)
saveBookSong(book.songId.toString())
})
function saveBook(book) {
db.transaction( (tx) => {
tx.executeSql(
`INSERT INTO books (id, description, img, name, song_id)
VALUES (?, ?, ?, ?, ?)`,
[book.id, book.description, book.img, book.name, book.songId],
() => {
console.log("Saved!!", book.id)
}
);
});
}
function saveBookSong(id) {
axios
.get(`songs/${id}`)
.then((bookSong) => {
bookSong.data.forEach((song) => {
db.transaction((tx) => {
tx.executeSql(
`INSERT INTO songs (id, book, book_id, data, int_song_number, lang, search_title, song_number, title, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
song.id,
song.book,
song.bookId,
song.data,
song.intSongNumber,
song.lang,
song.searchTitle,
song.songNumber,
song.title,
song.url,
],
() => {
}
);
});
});
})
.catch((err) => {
console.log(err);
});
}
uj5u.com熱心網友回復:
我假設您希望并行保存所有書籍。我會這樣做:
useEffect( () => {
const bookSavings = Books.map(async (book) =>{
await saveBook(book)
await saveBookSong(book.songId.toString())
});
// If you want to wait for all books to be saved
await Promise.all(bookSavings);
// ... Whatever else you want to do in your useEffect
}, [Books])
好的,但你不能簡單地await saveBook因為saveBookSong它們不是async函式。讓我們繼續前進。
在底層,異步函式只是回傳 Promise 的函式。我們實際上await可以做出任何承諾。因此,您可以通過將它們包裝在 Promise 中來制作saveBook和等待,如下所示:saveBookSong
function saveBook(book) {
return new Promise((resolve) => {
db.transaction( (tx) => {
tx.executeSql(
`INSERT INTO books (id, description, img, name, song_id)
VALUES (?, ?, ?, ?, ?)`,
[book.id, book.description, book.img, book.name, book.songId],
() => {
console.log("Saved!!", book.id)
resolve(); // <- THIS IS IMPORTANT
}
);
});
});
}
編輯:
第二個函式需要一點額外的關心,因為正如你所指出的,它包含一個回圈。但是,這與您擁有的頂級.map功能并沒有真正的不同。這是我的(未經測驗的)建議,希望您可以從這里開始作業。我將函式一分為二,以使其更易于理解:
async function saveBookSong(id) {
const bookSong = await axios.get(`songs/${id}`);
const savePromises = bookSong.data.map(song => {
return saveSong(song);
});
await Promise.all(savePromises);
}
function saveSong(song) {
return new Promise((resolve) => {
db.transaction((tx) => {
tx.executeSql(
`INSERT INTO songs (id, book, book_id, data, int_song_number, lang, search_title, song_number, title, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
song.id,
song.book,
song.bookId,
song.data,
song.intSongNumber,
song.lang,
song.searchTitle,
song.songNumber,
song.title,
song.url,
],
resolve
);
}
}
}
uj5u.com熱心網友回復:
如果我沒記錯的話 .map() 不知道異步。所以我會為你的問題提出兩種解決方案:
1)
useEffect( () => {
Books.map ((book) =>{
saveBook(book).then(() => saveBookSong(book.songId.toString()))
}, [Books])
在這種情況下,您在執行第一個函式后使用 then 。
2)
useEffect( () => {
const manageBooks = async() => {
for (book of Books) {
await saveBook(book);
await saveBookSong(book.songId.toString());
}
}
}, [Books])
您可以使用 async for 回圈,該回圈將在移動到另一個任務之前等待執行第一個任務
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/525584.html
