使用node-isbn更新图书对象字段后无法持久化修改的解决方法
解决node-isbn异步更新图书对象无法持久化的问题
这个问题的核心是异步操作的执行时机导致的,我来一步步给你拆解原因和解决方案:
为什么你的代码看不到更新?
isbn.resolve()是基于Promise的异步操作,当你在forEach循环里发起这个请求时,循环不会等待异步请求完成就直接执行了后面的console.log(item)。这时候then里的字段赋值逻辑还没运行,所以你看到的还是原始的空字段。
不过要说明的是:你其实已经在修改item对象本身了(因为JS对象是引用类型),只是你打印的时机太早。如果把console.log(item)移到then回调里,你会发现字段已经被更新了:
.then(function (book) { item.num_pages = book.pageCount; item.publication_year = book.publishedDate.replace( /^\D+/g, ''); console.log(item); // 这里能看到更新后的字段 })
但这种零散的处理方式不利于后续统一使用更新后的图书数组,所以更推荐下面的规范写法:
解决方案1:用for...of + await串行处理
这种方式会逐个处理图书,确保每一个异步请求完成后再进行下一个,适合需要按顺序处理的场景:
const isbn = require('node-isbn'); var books = []; // 假设已被填充 async function updateBooks() { // 使用for...of循环,配合await等待异步操作完成 for (const item of books) { if (item.publication_year === '' || item.num_pages === '') { try { // 等待ISBN查询结果返回 const book = await isbn.provider(['openlibrary', 'google']).resolve(item.isbn); // 更新字段 item.num_pages = book.pageCount; item.publication_year = book.publishedDate.replace(/^\D+/g, ''); } catch (err) { console.log('Book not found', err); } } // 此时打印的是已经完成更新的item console.log(item); } } // 调用异步函数 updateBooks();
解决方案2:用Promise.all并行处理
如果你的图书数量较多,想要提高处理效率,可以用Promise.all同时发起所有异步请求,等待全部完成后再获取更新后的数组:
const isbn = require('node-isbn'); var books = []; // 假设已被填充 async function updateBooks() { // 生成所有需要执行的异步任务数组 const updateTasks = books.map(async (item) => { if (item.publication_year === '' || item.num_pages === '') { try { const book = await isbn.provider(['openlibrary', 'google']).resolve(item.isbn); item.num_pages = book.pageCount; item.publication_year = book.publishedDate.replace(/^\D+/g, ''); } catch (err) { console.log('Book not found', err); } } return item; }); // 等待所有异步任务完成,得到更新后的图书数组 const updatedBooks = await Promise.all(updateTasks); // 统一打印所有更新后的图书 console.log(updatedBooks); } updateBooks();
这两种方式都能确保你在合适的时机拿到更新后的图书对象,解决你看不到字段更新的问题。
内容的提问来源于stack exchange,提问作者andrei
相关产品推荐
相关产品推荐

