如何在产品数据处理中获取二维码Promise的结果值?
问题:如何获取Promise对象中的[[PromiseResult]]值?
我通过API获取产品数据填充表格,调用QRCODES接口生成对应二维码图片,但传入表格的结果数组中,二维码图片地址字段返回的是Promise对象,而非实际的图片地址。
相关代码
const setTable = async () => { console.log(selectedChannel); productsService.getProducts(selectedChannel.name, selectedCategory.id).then(data => { setProducts(data.data) const dataTable = [] const allArray = data.data console.log(allArray) let row = {} let link = '' let qrImage = '' allArray.forEach(product => { link = "https://motitools.deco.cl/" + selectedChannel.name + "/es-CL/products/" + product.slug qrImage = QRCode.toDataURL(link) row = { "imagenQr": qrImage, "category": product.category, "name": product.name, "price": product.price, "image": product.image } dataTable.push(row) }); console.log(dataTable) setTableConten(dataTable) }); }
执行结果
imagenQr: Promise [[Prototype]]: Promise [[PromiseState]]: "fulfilled" [[PromiseResult]]: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL
补充信息
- 使用
qrImage = await QRCode.toDataURL(link)时出现报错; - 使用
QRCode.toDataURL(link).then( data => console.log(data))能在控制台打印出所有二维码地址,但不知道如何将该值赋值给变量。
我是JavaScript新手。
解决方案
问题出在QRCode.toDataURL是异步函数,返回的是Promise对象,直接赋值得到的不是最终结果;同时forEach不支持异步等待,即使在回调里用await也不会生效。可以按以下方式修改代码:
const setTable = async () => { console.log(selectedChannel); // 用await替代then,避免回调嵌套,同时获取接口返回数据 const data = await productsService.getProducts(selectedChannel.name, selectedCategory.id); setProducts(data.data); const allArray = data.data; console.log(allArray); // 用map遍历产品,每个处理逻辑包装成异步函数,返回Promise const dataTablePromises = allArray.map(async (product) => { const link = `https://motitools.deco.cl/${selectedChannel.name}/es-CL/products/${product.slug}`; // 用await获取二维码的实际base64地址 const qrImage = await QRCode.toDataURL(link); return { imagenQr: qrImage, category: product.category, name: product.name, price: product.price, image: product.image }; }); // 等待所有二维码生成完成,得到完整的表格数据数组 const dataTable = await Promise.all(dataTablePromises); console.log(dataTable); setTableConten(dataTable); };
关键说明
- 替换forEach为map:map会返回一个包含所有异步任务的Promise数组,方便后续统一等待;而forEach不会处理异步回调的执行顺序,会直接跳过等待继续执行后续代码。
- 使用await和Promise.all:
await必须在async函数内使用,这里把map的回调设为async,就能安全获取二维码的实际地址;Promise.all会等待所有异步任务完成后,返回所有结果组成的数组,此时dataTable里的imagenQr就是实际的图片地址,而非Promise对象。 - 扁平化异步代码:把外层的
then改成await,避免回调嵌套,让代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者Motias
相关产品推荐
相关产品推荐

