如何在JavaScript中等待函数执行完毕后再执行后续代码?
嘿,这个问题其实是JavaScript里最常见的异步执行坑之一——你写的tt()函数里用了setInterval,这玩意儿属于异步任务,会被丢到事件队列里排队,主线程可不会等它执行完,会直接往下跑document.getElementById("b").innerHTML = "b"这行代码,所以自然是先显示b再显示a啦。
要解决这个问题,我们得让line b的代码等待tt()里的异步操作完成后再执行,这里有三种常用的实现方式,你可以根据场景选择:
方法1:回调函数(最传统的异步处理方式)
我们给tt函数加一个回调参数,当定时器里的操作完成时,调用这个回调函数,把line b的逻辑放到回调里:
var time = Math.floor(Math.random() * 11) * 1000; function tt(callback){ var tts = setInterval(function() { document.getElementById("a").innerHTML = "a"; clearInterval(tts); // 异步操作完成后,触发传入的回调 callback(); }, time); } // 调用tt时,把line b的逻辑作为回调传进去 tt(function() { document.getElementById("b").innerHTML = "b"; // 现在这行只会在tt执行完后运行 });
这种方式简单直接,适合简单的异步场景,但如果有多层嵌套异步,容易出现“回调地狱”,代码可读性会变差。
方法2:Promise + then(ES6标准异步方案)
把tt函数改成返回一个Promise对象,当异步操作完成时标记resolve,然后用.then()来执行后续逻辑:
var time = Math.floor(Math.random() * 11) * 1000; function tt(){ return new Promise((resolve) => { var tts = setInterval(function() { document.getElementById("a").innerHTML = "a"; clearInterval(tts); // 标记异步操作完成 resolve(); }, time); }); } // 调用tt,用then指定后续执行的逻辑 tt().then(() => { document.getElementById("b").innerHTML = "b"; });
Promise解决了回调地狱的问题,让异步流程更清晰,是现在主流的异步处理基础方案。
方法3:async/await(Promise语法糖,可读性拉满)
这是基于Promise的语法糖,能让异步代码看起来像同步代码一样直观:
var time = Math.floor(Math.random() * 11) * 1000; function tt(){ return new Promise((resolve) => { var tts = setInterval(function() { document.getElementById("a").innerHTML = "a"; clearInterval(tts); resolve(); }, time); }); } // 用async函数包裹逻辑,await等待tt完成 async function run() { await tt(); // 这里会暂停执行,直到tt的Promise被resolve document.getElementById("b").innerHTML = "b"; // 等tt完成后才会执行这行 } run();
这种方式的代码逻辑和我们的期望完全一致,可读性最高,推荐在现代项目中使用。
另外补充一句:不管你的异步操作是定时器、AJAX请求还是其他,核心思路都是一样的——把异步操作的结束点暴露出来(回调、Promise),让后续逻辑在这个结束点触发。
内容的提问来源于stack exchange,提问作者Mohamed Maher
相关产品推荐
相关产品推荐

