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

如何在Promise内部实现代码等待获取异步返回值?

问题根因

await 关键字仅允许在 async 声明的异步函数内部使用,你当前写await的位置是request的普通匿名回调函数内,该函数未被标记为async,属于语法错误,无法正常执行。

除了await使用位置的问题,原代码还有几个隐性逻辑bug:

  • 请求报错分支执行reject后没有阻断后续逻辑,会出现已拒绝Promise后又尝试执行resolve的冲突
  • 无关联联系人的分支执行resolve(null)后同样没有阻断,后续会执行到末尾的resolve(contacBID),此时contacBID未定义,会覆盖之前的resolve结果
  • 没有对JSON.parse、异步联系人查询操作做异常捕获,一旦解析失败或者查询报错,会导致Promise永远悬停,不会进入reject分支
修复方案

最小改动方案

不需要调整整体结构,只需要给request的回调函数加上async标记,补全分支阻断和异常捕获即可,完全兼容你现有返回Promise的调用要求:

const optionsA = {
    method: "GET",
    url: "https://example.com",
    qs: { hapikey: "smthng" }
};
return new Promise(function(resolve, reject){
    // 给回调加async标记,内部即可合法使用await
    request(optionsA, async function (error, response, body) {
        if(error){
            logResponse("could not reach boondmanager status:", response.statusCode);
            reject("error while reading");
            // 阻断后续逻辑执行
            return;
        }

        try {
            const dealH = JSON.parse(body);
            const associatedVids = dealH?.associations?.associatedVids;
            // 无关联联系人直接返回
            if(!associatedVids || associatedVids[0] === undefined){
                console.log("Not linked at all with a contact")
                resolve(null);
                return;
            }

            const ContactHID = associatedVids[0];
            // 此处await会等待异步操作执行完成,拿到最终结果而非Promise对象
            const contacBID = await ContactIDFinder.findingBoondIDcontact(ContactHID);
            console.log(`attempt at finding the BID for the contact linked to the company led to : ${contacBID}`);
            
            if (contacBID != null) { 
                console.log("associated BID is : "+ contacBID)
            } else {
                console.log("linked with a contact unsynchronized")
            }
            resolve(contacBID);
        } catch(err) {
            // 捕获JSON解析、异步查询的所有异常,统一走reject逻辑
            reject(err);
        }
    });
});

更规范的重构方案

回调嵌套的写法可读性和可维护性较差,可以先把回调风格的request封装为通用Promise工具函数,全程用async/await平铺写逻辑,最终返回值依然是Promise,和你后续的调用逻辑完全适配:

// 先把request封装为通用Promise请求方法
function requestPromise(options) {
    return new Promise((resolve, reject) => {
        request(options, (error, response, body) => {
            if (error) {
                logResponse("could not reach boondmanager status:", response.statusCode);
                reject("error while reading");
                return;
            }
            resolve({response, body});
        })
    })
}

// 外层标记为async,内部可直接使用await
async function getLinkedContactBoondID() {
    const optionsA = {
        method: "GET",
        url: "https://example.com",
        qs: { hapikey: "smthng" }
    };

    try {
        const { body } = await requestPromise(optionsA);
        const dealH = JSON.parse(body);
        const associatedVids = dealH?.associations?.associatedVids;
        if(!associatedVids || associatedVids[0] === undefined){
            console.log("Not linked at all with a contact")
            return null;
        }

        const ContactHID = associatedVids[0];
        const contacBID = await ContactIDFinder.findingBoondIDcontact(ContactHID);
        console.log(`attempt at finding the BID for the contact linked to the company led to : ${contacBID}`);
        
        if (contacBID != null) { 
            console.log("associated BID is : "+ contacBID)
        } else {
            console.log("linked with a contact unsynchronized")
        }
        // async函数的返回值会自动包装为Promise,和原逻辑完全兼容
        return contacBID;
    } catch(err) {
        throw err;
    }
}

// 后续调用既可以用.then()链式调用,也可以在async函数里用await拿结果
// getLinkedContactBoondID().then(res => { /* 你的后续逻辑 */ })

提示:你当前使用的requestnpm包已经官方停止维护,如果是新项目可以直接替换为原生fetch、axios等原生支持Promise的请求库,省去手动封装Promise的步骤。

内容的提问来源于stack exchange,提问作者Louis Tonnevy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:33:24