Node.js中如何获取Promise的then()返回值并在外部使用
问题根本原因
这是JavaScript异步机制的典型表现:google.youtube('v3').search.list()是异步方法,返回Promise对象,代码不会等待Promise状态变为resolved/rejected,就会直接执行后面的console.log(enlace),所以你拿到的是处于pending状态的Promise对象。
另外你原来的代码还存在一个逻辑问题:forEach循环内部的return只会终止当前单次遍历,不会将link的值返回到.then()的外层,所以就算Promise执行完成,你也拿不到对应的返回值。
解决方案
推荐优先使用async/await语法,代码可读性更高,逻辑更清晰:
client.on("messageCreate", async msg => { if (msg.content.toLowerCase().startsWith('-p')) { try { msg.content = msg.content.slice(3); // 等待异步请求执行完成,拿到接口返回结果 const response = await google.youtube('v3').search.list({ key: process.env.YOUTUBE_TOKEN, part: 'id', q: msg.content, maxResults: 1 }); const { data } = response; // 你设置了maxResults=1,直接取第一个元素的videoId即可 const enlace = data.items[0]?.id.videoId; // 所有需要用到enlace的后续逻辑都可以写在这里 console.log(enlace); // 例:播放音乐、返回链接给用户等操作 } catch (err) { // 统一捕获请求错误 console.error('获取Youtube链接失败:', err); } } })
如果你习惯用.then()链式写法,只需要把所有依赖enlace的逻辑都放在.then()回调内部即可,不要尝试在全局同步获取异步返回值:
client.on("messageCreate", msg => { if (msg.content.toLowerCase().startsWith('-p')) { msg.content = msg.content.slice(3); google.youtube('v3').search.list({ key: process.env.YOUTUBE_TOKEN, part: 'id', q: msg.content, maxResults: 1 }).then((response) => { const { data } = response; const enlace = data.items[0]?.id.videoId; // 所有需要用到enlace的逻辑都在这里执行 console.log(enlace); // 也可以封装成独立函数调用 handleLink(enlace); }).catch((err) => console.log(err)); } }) // 后续处理逻辑封装 function handleLink(link) { // 在这里写你的后续业务代码 }
注意:不要尝试将异步返回的结果赋值给全局变量后同步调用,JavaScript事件循环机制决定了同步代码一定会先于异步回调执行,这种写法必然会拿到undefined或者pending状态的Promise。
内容的提问来源于stack exchange,提问作者Cristian David Moraleda
相关产品推荐
相关产品推荐

