JavaScript中的同步方法及异步方法示例代码
作者:linab112
1.代码说明
const saveTem = () => { // 校验处理 const res = check() if (!res) { return } addTemplateRef.value.openModal() }
这段代码中,check方法返回的是true和false,是一个普通方法,
openModal也是一个普通方法,没有返回值,
这段代码的执行顺序是依次执行的,因为没有任何异步操作,即使这个方法被async修饰,代码的执行顺序也是依次执行的
什么是异步操作,可以简单理解为方法被async修饰,axios及fetch请求及setTimeout方法等。
返回值为promise的方法不一定为异步方法,也就是说异步方法不能通过返回值进行判断
但是异步方法的返回值一定是promise,必须使用await或者.then才能获取实际返回值
2.async修饰的方法和非async修饰的方法的区别
1. 返回值不同
async 函数:
总是返回一个 Promise 对象
如果返回非 Promise 值,会自动用 Promise 包装
如果抛出异常,返回被拒绝(rejected)的 Promise
普通函数:
直接返回 return 语句指定的值
如果没有 return,返回 undefined
抛出异常会直接中断执行
2. 执行方式不同
async 函数:
内部可以使用 await 暂停执行,使用await后会等待后面的方法执行完成,再继续后续的内容
不会阻塞主线程
普通函数:
同步执行
会阻塞后续代码直到执行完成
async function asyncFunc() { console.log(1); await new Promise(resolve => setTimeout(resolve, 1000)); console.log(2); } function syncFunc() { console.log(1); setTimeout(() => console.log(2), 1000); console.log(3); } asyncFunc(); // 输出: 1, 2 (1秒后) syncFunc(); // 输出: 1, 3, 2 (1秒后)
3. 错误处理不同
async 函数:
抛出的错误会被捕获并转换为 rejected Promise
需要使用 try/catch 或 .catch() 捕获错误
普通函数:
错误会直接抛出
需要使用 try/catch 捕获同步错误
4. 调用方式不同
async 函数:
必须用 await 或 .then() 才能获取结果
直接调用会返回 Promise 对象而非实际结果
普通函数:
直接调用获取返回值
5. 适用场景
使用 async 函数的场景:
需要处理 Promise 链式调用,使用之前的.then会导致回调地狱问题,使用await可以让多个异步操作按照顺序执行,使代码更加整洁
需要顺序执行多个异步操作
需要更清晰的异步代码结构
使用普通函数的场景:
纯同步操作
示例
async function getData() { console.log('开始获取数据...'); // 1. 同步执行 const result = await fetchData(); // 2. 遇到 await,暂停执行并等待 Promise 解决 console.log(result); // 4. Promise 解决后继续执行 return result; // 5. 返回结果(包装在 Promise 中) } // 模拟异步函数 function fetchData() { return new Promise(resolve => { setTimeout(() => resolve('数据获取成功'), 1000); // 3. 1秒后解决 Promise }); } // 调用示例 getData().then(data => console.log('最终结果:', data)); // 6. 接收最终结果
详细执行流程:
同步阶段:
调用 getData() 函数
执行第一行
console.log
('开始获取数据...')(立即输出)
遇到 await:
执行 fetchData()(返回一个 Promise)
await 会暂停
getData()
函数的执行,将控制权交回事件循环此时
getData()
返回一个未解决的 Promise,pending状态的promise
异步等待:
fetchData()
中的setTimeout
开始计时(1秒)JavaScript 引擎可以处理其他任务
Promise 解决:
1秒后,
setTimeout
回调执行,Promise 被解决(resolve)await
接收到解决的值'数据获取成功'
getData()
函数恢复执行
继续执行 async 函数:
将解决的值赋给
result
执行
console.log(result)
(输出 "数据获取成功")执行
return result
(这里会包装成一个promise)
处理最终结果:
.then()
回调被执行,输出 "最终结果: 数据获取成功"
关键点说明:
await
会暂停当前 async 函数的执行(但不会阻塞主线程)async 函数在遇到第一个
await
时就会立即返回一个 Promise被暂停的函数会在 Promise 解决后从暂停点继续执行
return 的值会自动包装成 Promise
3.不使用await的场景
场景 1:明确需要 Promise 对象时
const fetchData = async () => { /* ... */ }; // 需要传递 Promise 给其他逻辑 const promise = fetchData(); // 不 await,保留 Promise promise.then((data) => { /* ... */ });
场景 2:并行多个异步任务(用 Promise.all)
const getUser = async () => { /* ... */ }; const getPosts = async () => { /* ... */ }; // 不单独 await,直接收集 Promises const [user, posts] = await Promise.all([getUser(), getPosts()]);
关键点说明
并行执行:
getUser()
和getPosts()
会同时开始执行,而不是一个接一个执行。Promise.all 的作用:
接收一个 Promise 数组作为输入
返回一个新的 Promise,当所有输入的 Promise 都解决(resolve)时,这个新 Promise 才会解决
解决值是一个数组,包含所有输入 Promise 的解决值,顺序与输入数组一致
解构赋值:
const [user, posts] = ...
将 Promise.all 返回的数组解构为两个变量
执行流程
调用
getUser()
和getPosts()
会立即返回两个 Promise 对象这两个异步操作会同时开始执行(假设它们不互相依赖)
Promise.all
会等待这两个 Promise 都完成当两者都完成后,结果会被解构到
user
和posts
变量中
与顺序执行的对比
如果写成这样就是顺序执行(不推荐):
const user = await getUser(); // 等待这个完成 const posts = await getPosts(); // 然后才开始这个
而使用 Promise.all
的方式总耗时大约等于较慢的那个操作的时间,而不是两者时间相加。
注意事项
如果其中一个 Promise 被拒绝(reject),整个
Promise.all
会立即拒绝适合用于彼此独立的异步操作
如果操作之间有依赖关系,可能需要顺序执行
4.总结
方法中如果没有异步方法,按照顺序依次执行
如果有异步方法,没有使用await或者.then,不会依次执行,会先执行异步方法后面的方法,再执行异步方法
如果需要控制方法内,异步方法的顺序,可以使用await或者.then,需要注意如果要使用await,则方法必须被async修饰
使用async修饰的方法,返回值为promise,需要使用await或者.then获取返回值
返回值为promise不一定是异步方法,异步方法的返回值一定是promise
常见的异步方法为async修饰的方法,setimeout方法,axios方法,fetch方法
到此这篇关于JavaScript中的同步方法及异步方法的文章就介绍到这了,更多相关js同步方法及异步方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!