JavaScript中如何实现HTTPS GET请求后的顺序执行?
问题原因
Node.js里的https.get是异步I/O操作,它不会阻塞后续同步代码的执行。当你调用它时,JavaScript引擎会把这个异步任务丢到事件队列里,先继续执行后面的同步代码(也就是console.log("funcA")和console.log("funcB")),等网络请求完成后,才会从事件队列里取出回调函数执行,所以才会出现你看到的输出顺序。
实现预期输出的方案
要保留原有代码结构,核心是把回调式的https.get转成Promise,再用async/await控制执行顺序,具体步骤如下:
把
https.get包装成Promise
回调式API转Promise是异步编程的常用操作,手动封装即可:function getPromise(url) { return new Promise((resolve) => { https.get(url, (response) => { console.log("http call"); resolve(); // 请求完成后标记Promise成功 }); }); }改造
funcA为async函数
用await等待上面的Promise完成,确保console.log("funcA")在"http call"之后执行:async function funcA() { var sampleUrl = "https://v2.jokeapi.dev/joke/Programming"; await getPromise(sampleUrl); // 等待异步请求完成 console.log("funcA"); }控制
funcB的执行时机funcA现在是async函数,返回的是Promise,必须等它执行完再打印funcB,两种实现方式:// 方式1:用.then()链式调用 funcA().then(() => { console.log("funcB"); }); // 方式2:用async立即执行函数(更贴近同步写法) (async () => { await funcA(); console.log("funcB"); })();
完整代码示例
const https = require('https'); // 别忘了引入https模块 function getPromise(url) { return new Promise((resolve) => { https.get(url, (response) => { console.log("http call"); resolve(); }); }); } async function funcA() { var sampleUrl = "https://v2.jokeapi.dev/joke/Programming"; await getPromise(sampleUrl); console.log("funcA"); } // 调用执行 funcA().then(() => { console.log("funcB"); });
执行后输出顺序完全符合预期:
http call funcA funcB
经验分享
- Node.js从v10开始提供
util.promisify工具函数,可直接把符合(err, res)格式的回调API转成Promise,不过https.get的回调只有response参数,手动封装反而更灵活; async/await是Promise的语法糖,能让异步代码看起来像同步代码,但要记住:async函数本身是异步的,调用它不会阻塞后续同步代码,必须用await或者.then()等待它完成;- 理解JavaScript的事件循环机制是搞懂异步顺序的核心:同步任务优先执行,异步任务(I/O、定时器等)会被放到对应事件队列,等同步代码执行完毕后才会依次处理队列里的任务。
内容的提问来源于stack exchange,提问作者John Pham
相关产品推荐
相关产品推荐

