如何实现在前一个函数执行完成后调用后续函数?解决函数执行顺序异常导致的数据混乱问题
这是个非常常见的异步代码执行顺序问题,咱们来一步步拆解解决它~
问题根源
你遇到的问题是因为first_function是异步函数(async function),当你直接调用first_function();时,它会立刻返回一个Promise对象,主线程不会等待它内部的异步操作完成,就直接执行了后面的second_function();,所以才会出现second_function先执行的情况。
解决方案
下面提供两种最常用的解决方式,你可以根据自己的代码场景选择:
方案1:用async/await包裹调用逻辑
因为await关键字只能在async函数内部使用,所以我们可以把调用两个函数的代码放到一个异步初始化函数里:
// 定义一个异步初始化函数 async function init() { // 等待first_function完全执行完成 await first_function(); // 再执行second_function second_function(); } // 调用初始化函数启动流程 init();
这样init函数会严格按照顺序:先等first_function的所有异步操作完成,再执行second_function,完美保证顺序。
方案2:用Promise的.then()链式调用
如果你不想额外定义一个init函数,也可以直接利用async函数返回Promise的特性,用.then()来指定后续操作:
first_function().then(() => { // 当first_function执行完成后,执行这里的代码 second_function(); });
当first_function内部的所有异步操作完成,Promise状态变为resolved时,就会触发.then()里的回调,执行second_function。
额外注意点
你在first_function里写了await name();,但目前name只是普通函数,不是异步函数,这个await其实不会起到等待作用。如果name函数内部未来会加入异步操作(比如接口请求、定时器等),记得把name改成异步函数:
async function name() { // 如果有异步操作,比如接口请求,这里要加await // await fetch('/some-api'); if (condition == true) { let tdbody = document.createElement('td'); tdbody.classList.add("class1"); let tdbodytext = document.createTextNode(userincourseres[i].fullname); tdbody.appendChild(tdbodytext); trbody.appendChild(tdbody); } }
这样first_function里的await name()才会真正等待name的异步操作完成后再继续执行。
内容的提问来源于stack exchange,提问作者Abdallah_mohammad_90

