You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript异步函数返回Promise{<pending>}而非预期值的问题

问题与解决方案:异步函数调用导致的Promise pending及返回值错误

在Express框架的TypeScript代码中,fetchCellId调用异步函数getCellId请求第三方POST接口时,遇到两个核心问题:

  • 直接赋值results = getCellId(...)得到的是Promise{<pending>},使用then回调也无法同步获取结果;
  • 用await关键字时,得到的是庞大的ServerResponse对象,而非预期的第三方接口返回数据。

原代码片段

const fetchCellId = async (req: Request, res: Response,next: NextFunction)=>{
    const cellId = req.query.cellId as string;
    let results;
  
    try {
      results = getCellId(req, res, next);
      results.then(data =>{
        return data;
      });
      
      console.log('look78');
      console.log(results);
      await redisClient.set(cellId, JSON.stringify(results), {
        EX: 180,
        NX: true,
      });
      console.log('look 54')
      res.send({
        fromCache: false,
        data: results,
      });
      console.log('look 56') 
    
  }catch (error) {
      console.error(error);
      res.status(404).send("Data unavailable");
    }
  }

const getCellId = async (req: Request, res: Response, next: NextFunction) => {
    console.log('look 10');
    let id: string = req.query.cellId as string;
    console.log(id);
    let cid = id.substring(0, 5);
    let lac = id.substring(12,16);
    let mcc = id.substring(6, 9);
    let mnc = id[10];
    console.log(cid);
    console.log(lac);
    console.log(mcc);
    console.log(mnc);
    let response: AxiosResponse = await axios.post(`https://eu1.unwiredlabs.com/v2/process.php`, {
        'token': 'pk.ccd04*****######6',
        'radio': 'lte',
        'mcc': mcc,
        'mnc': mnc,
        'cells': [{
            'lac': lac,
            'cid': cid
        }]
    });
    const cellIdRes = await res.status(200).json({
      "lng": response.data.lon,
      "lat": response.data.lat,
      "acc": response.data.accuracy
    });
    console.log(cellIdRes);
    return cellIdRes;
};

问题原因分析

  1. Promise pending问题:异步函数调用后必须用await等待Promise决议完成,直接赋值或仅用then回调无法阻塞后续代码执行,导致后续使用results时仍处于pending状态。
  2. 返回ServerResponse问题:getCellId中调用的res.status(200).json(...)方法返回的是Express的ServerResponse对象,而非第三方接口的解析数据。错误地将该响应对象作为函数返回值,导致await getCellId(...)拿到的是res对象而非预期数据。

修正后的代码

1. 修正getCellId函数(职责分离:仅处理数据获取与转换)

const getCellId = async (req: Request, res: Response, next: NextFunction) => {
    console.log('look 10');
    const id: string = req.query.cellId as string;
    console.log(id);
    const cid = id.substring(0, 5);
    const lac = id.substring(12,16);
    const mcc = id.substring(6, 9);
    const mnc = id[10];
    console.log(cid, lac, mcc, mnc);

    const response: AxiosResponse = await axios.post(`https://eu1.unwiredlabs.com/v2/process.php`, {
        'token': 'pk.ccd04*****######6',
        'radio': 'lte',
        'mcc': mcc,
        'mnc': mnc,
        'cells': [{
            'lac': lac,
            'cid': cid
        }]
    });

    // 直接返回处理后的第三方接口数据,将响应发送逻辑交给上层函数
    return {
        "lng": response.data.lon,
        "lat": response.data.lat,
        "acc": response.data.accuracy
    };
};

2. 修正fetchCellId函数(用await等待异步结果)

const fetchCellId = async (req: Request, res: Response, next: NextFunction) => {
    const cellId = req.query.cellId as string;
  
    try {
        // 用await等待异步函数完成,获取实际数据
        const results = await getCellId(req, res, next);
        console.log('look78');
        console.log(results);

        // 存入Redis时使用实际数据而非Promise
        await redisClient.set(cellId, JSON.stringify(results), {
            EX: 180,
            NX: true,
        });
        
        console.log('look 54');
        // 统一在该函数中发送响应
        res.send({
            fromCache: false,
            data: results,
        });
        console.log('look 56'); 
    } catch (error) {
        console.error(error);
        res.status(404).send("Data unavailable");
    }
};

关键修正点

  • 异步函数调用必须搭配await才能获取最终结果,否则仅能拿到未决议的Promise;
  • 拆分函数职责:数据处理(getCellId)与HTTP响应发送(fetchCellId)分离,避免混淆返回值类型;
  • 确保每个函数只完成单一任务,提升代码可维护性与可读性。

内容的提问来源于stack exchange,提问作者SUNDARAM SRIVASTAVA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:55:20