当前位置: 首页 > news >正文

js中的同步方法及异步方法

目录

1.代码说明

2.async修饰的方法和非async修饰的方法的区别

3.不使用await的场景

4.总结


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. 接收最终结果

详细执行流程:

  1. 同步阶段

    • 调用 getData() 函数

    • 执行第一行 console.log('开始获取数据...')(立即输出)

  2. 遇到 await

    • 执行 fetchData()(返回一个 Promise)

    • await 会暂停 getData() 函数的执行,将控制权交回事件循环

    • 此时 getData() 返回一个未解决的 Promise,pending状态的promise

  3. 异步等待

    • fetchData() 中的 setTimeout 开始计时(1秒)

    • JavaScript 引擎可以处理其他任务

  4. Promise 解决

    • 1秒后,setTimeout 回调执行,Promise 被解决(resolve)

    • await 接收到解决的值 '数据获取成功'

    • getData() 函数恢复执行

  5. 继续执行 async 函数

    • 将解决的值赋给 result

    • 执行 console.log(result)(输出 "数据获取成功")

    • 执行 return result(这里会包装成一个promise)

  6. 处理最终结果

    • .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()]);

关键点说明

  1. 并行执行getUser() 和 getPosts() 会同时开始执行,而不是一个接一个执行。

  2. Promise.all 的作用

    • 接收一个 Promise 数组作为输入

    • 返回一个新的 Promise,当所有输入的 Promise 都解决(resolve)时,这个新 Promise 才会解决

    • 解决值是一个数组,包含所有输入 Promise 的解决值,顺序与输入数组一致

  3. 解构赋值const [user, posts] = ... 将 Promise.all 返回的数组解构为两个变量

执行流程

  1. 调用 getUser() 和 getPosts() 会立即返回两个 Promise 对象

  2. 这两个异步操作会同时开始执行(假设它们不互相依赖)

  3. Promise.all 会等待这两个 Promise 都完成

  4. 当两者都完成后,结果会被解构到 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方法

相关文章:

  • Unity引擎源码-物理系统详解-其一
  • 抗量子计算攻击的数据安全体系构建:从理论突破到工程实践
  • C# 通用OCR识别
  • 基于TI AM6442+FPGA解决方案,支持6网口,4路CAN,8个串口
  • CSS3 基础知识、原理及与CSS的区别
  • 洛谷 P3374 【模板】树状数组 1(树状数组解法)
  • Qt在统信UOS及银河麒麟Kylin系统中进行软件开发的环境配置,打包发布和注意事项
  • spark sql基本操作
  • 百度智能云千帆携手联想,共创MCP生态宇宙
  • 【计算机网络 第8版】谢希仁编著 第四章网络层 题型总结3 SDN OpenFlow
  • webpack重构优化
  • 运行Spark程序-在Idea中
  • PostgreSQL pg_dump 与 Oracle expdp 对比
  • Web 架构之攻击应急方案
  • 汉得 x 汇川联合动力|H-ZERO PaaS零衍平台,助力全新企业门户上线!
  • 【Git】合并和变基的区别
  • 三轴云台之减震和固定技术篇
  • Grok 3.5 跳票,ChatGPT 悄悄升级:GitHub 深度研究 + PDF 导出!
  • 实现 STM32 PWM 输出:原理、配置与应用详解
  • 代码随想录算法训练营第60期第三十五天打卡
  • 中国巴西关于乌克兰危机的联合声明
  • 沙县小吃中东首店在沙特首都利雅得开业,首天营业额5万元
  • 印称印巴军事行动总指挥同意将局势降级
  • 男子退机票被收票价90%的手续费,律师:虽然合规,但显失公平
  • 云南一男子持刀致邻居3死1重伤案二审开庭,未当庭宣判
  • 乘联分会:上半年车市价格竞争温和,下半年价格战或再开启