JavaScript async/await调用返回Promise<pending>问题排查
问题原因
核心是对JS异步执行逻辑和await的生效规则理解有偏差,具体两点:
getUsers是同步执行函数,没有返回Promise对象。当前实现中先初始化users为空数组,setTimeout的回调会被放入宏任务队列等待1秒后才执行,函数本身不会等待定时器触发,直接就把初始的空数组返回了。等1秒后回调执行给函数内部的users变量重新赋值时,函数早就执行完毕退出,外部根本拿不到定时器里赋值的用户数据。await关键字仅会等待Promise对象的状态变更。你用await等待同步返回的空数组时,不会产生任何等待效果,会立刻拿到空数组执行后续的find逻辑,自然查不到匹配用户;同时async声明的函数本身返回值就是Promise对象,直接调用不做后续链式处理的话,拿到的就是pending状态的Promise。
修正方法
把getUsers改造为返回Promise的函数,在定时器回调拿到完整用户数据后,调用resolve把数据传出,这样await就能正确等待1秒延迟结束,拿到真实的用户数组。如果需要拿到findUser最终的查询结果,需要通过await或者.then()处理它返回的Promise。
修正后的完整代码:
function getUsers() { // 返回Promise实例,让await可以感知异步操作的完成时机 return new Promise((resolve) => { setTimeout(() => { const users = [ { username: 'john', email: 'john@test.com' }, { username: 'jane', email: 'jane@test.com' }, ]; // 延迟结束、数据准备完成后,通过resolve把数据传递出去 resolve(users); }, 1000); }) } async function findUser(username) { // 此处await会暂停执行,直到Promise resolve后拿到完整用户数组 const users = await getUsers(); const user = users.find((item) => item.username === username); console.log(user); return user; } // 调用async函数需要处理返回的Promise,以下两种方式均可 // 1. 在async上下文中用await获取结果 // async function init() { // const targetUser = await findUser('john'); // console.log('查询结果:', targetUser); // } // init(); // 2. 用.then()注册回调拿到结果 findUser('john').then(user => { console.log('最终匹配用户:', user); });
运行后等待1秒会正确打印出{ username: 'john', email: 'john@test.com' },不会再出现拿不到值、返回pending Promise的问题。
内容的提问来源于stack exchange,提问作者George Go
相关产品推荐
相关产品推荐

