js学习9(同步和异步)
创始人
2025-05-29 14:16:30
0

同步和异步

### 前言:
不得不说,同步有同步的好处和坏处,异步有异步的好处坏处,各有利弊。

### 思量:
(1) 如果有一个操作很费时间,那么在同步执行的过程中,该操作就会阻断后面代码的执行,这在有时是不利的【这时可以考虑异步】
(2)如果某个操作建立在某个异步操作返回的结果基础上,此时如果异步操作还没完成这样就会导致这个操作无法正常运行【这时可以考虑同步】

js同步和异步 

### 前言:
(1) 像平时编写的js代码,都是从上往下依次执行的(不涉及到异步方法或代码),就是同步代码;
(2) 当然js用有些方法的执行过程是异步的,比如常见的setTimeout()、fetch()等等;


### 解决异步问题,实现异步编程:
## 方式1:回调函数
在异步函数执行完成后(或满足某一状态后),执行回调函数,这样就能确保回调函数一定在异步任务之后执行的
## 方式2:使用Promise(then)
Promise的resolve状态可以断定当前Promise是否完成,且then在resolved状态时被执行,从而保证了Promise之间的顺序
## 方式3:使用Promise(async&await)
async声明的异步函数,可以使用await来确保Promise处于resolved状态再执行其后的代码
## 方式4:使用Promise(all)
Promise.all([promise1,promise2,...])允许将多个Promise对象组成链,并按照顺序依次先后执行
## 方式5:使用生成器
生成器通过yield终止执行,同时提供next方法继续执行,形成一个终止再执行的驱动过程,同时会把异步任务按顺序加入线程,整个线程完成后按顺序返回结果

Promise

### 创建

new Promise((resolve,reject)=>{

        ...

})

### Promise链

Promise对象无论是then方法还是catch方法返回的依然是Promise对象,所以会形成Promise链。

### then和catch

当Promise成为resolved状态后,会执行then方法;

当Promise成为rejected状态后,会执行catch方法;
 

### resolve()和reject()

resolve([value])使当前Promise状态为resolved状态,且可以传value给下一个Promise;

reject(err)使当前Promise状态为rejected状态;

### 代码了解

const promise1 = new Promise((resolve, reject) => {

  // 异步函数
  setTimeout(() => {
    console.log(222);
    resolve('foo'); // 设为resolved状态
  }, 5000);
});
promise1.then((value) => {
  console.log(333,value); // 等待Promise中异步函数的完成
});

console.log(111,promise1); // 同步代码

### 更多学习

 Promise - JavaScript | MDN (mozilla.org)

 

async&await

### 简要:

async允许声明一个异步函数,返回的是一个Promise对象,await可以等待一个Promise对象的完成再执行其后代码

### 代码了解

async function f1() {

    return new Promise((resolve,reject)=>{

        setTimeout(() => {

            console.log(111);

            resolve();

        }, 5000);

    })

   

}

f1().then(()=>{

    console.log(222);

})

异步编程

 1. XMLHttpRequest

### 异步(默认情况)
xhr.open(method,url,async=true);
## 异步过程,可以通过onload和onerror监听状态进而使用回调处理
xhr.onload = function(){var data = JSON.parse(this.responseText);
}### 同步
xhr.open(method,url,async=false);
# 同步过程,会等请求完成再执行下面代码
var data = JSON.parse(xhr.responseText());### 说明
第一种默认异步请求,为保证能拿到数据并处理,使用了回调
第二种直接为同步请求,其后代码会等待请求响应完成后再执行,也是可以的

 2. setTimeout

### 异步执行(默认情况)
console.log(111);
// setTimeout是个异步方法
setTimeout(()=>{console.log(222);
},5000)
console.log(333);
## 结果:111 >> 333 >> 222### 使其同步执行,结果:111 >> 222 >> 333
## 方式1:回调
console.log(111);
function f1(callback) {setTimeout(() => {console.log(222);callback();}, 5000);
}
function f2() {console.log(333);
}
f1(f2);## 方式2:Promise(then)
console.log(111);
new Promise((resolve, reject) => {setTimeout(() => {console.log(222);resolve();}, 5000)
})
.then(()=>{console.log(333);
})## 方式3:Promise + async&await
console.log(111);
function f1() {return new Promise((resolve, reject) => {setTimeout(() => {console.log(222);resolve();}, 5000)})
}
// 使用async + await
(async function test() {await f1();    console.log(333)
})();### 总结:
(1) js中已经封装好的方法,一般用监听器回调的方式来解决异步问题;
(2) 自己编写异步代码,则可以使用Promise方式;

回调地狱

简要:

多个异步任务使用回调的方式来确保运行顺序,此时回调形成嵌套的多层缩进问题

 回调地狱代码(简略形式): 

function f1(callback) {setTimeout(() => {console.log(222);callback();}, 5000);
}
function f2(callback){setTimeout(() => {console.log(333);callback();}, 3000);
}
function f3() {console.log(444);
}f1(()=>{f2(()=>{f3();})
});

  解决改进 :

### 方式1:Promise(then)
function p1(){return new Promise((resolve,reject)=>{setTimeout(() => {console.log(111);resolve();}, 5000);})
} 
function p2(){return new Promise((resolve,reject)=>{setTimeout(() => {console.log(222);resolve();}, 3000);})
} 
function p3(){return new Promise((resolve,reject)=>{setTimeout(() => {console.log(333);resolve();}, 1000);})
} p1()
.then(()=>p2())
.then(()=>p3());## 方式2:Promise + async&await
function p1() {return new Promise((resolve,reject)=>{setTimeout(() => {console.log(111);resolve();}, 5000);})
}:
function p2() {return new Promise((resolve,reject)=>{setTimeout(() => {console.log(222);resolve();}, 5000);})
}
(async ()=>{await p1();await p2();console.log(333);
})();## 方式3:Promise.all()
p1 = new Promise((resolve,reject)=>{setTimeout(() => {console.log(111);resolve();}, 5000);
})
p2 = new Promise((resolve,reject)=>{setTimeout(() => {console.log(222);resolve();}, 5000);
})Promise.all([p1,p2])
.then(()=>{console.log(333);
});

相关内容

热门资讯

山西太钢不锈钢股份有限公司 2... 来源:证券日报 证券代码:000825 证券简称:太钢不锈 公告编号:2026-001 本公司及董...
把自己的银行贷款出借给别人,有... 新京报讯(记者张静姝 通讯员邸越洋)因贷款出借后未被归还,原告牛女士将被告杨甲、杨乙诉至法院,要求二...
金价暴跌,刚买的金饰能退吗?有... 黄金价格大跌,多品牌设置退货手续费。 在过去两三天,现货黄金价格经历了“过山车”般的行情,受金价下跌...
预计赚超2500万!“豆腐大王... 图片来源:图虫创意 在经历了一年亏损后,“豆腐大王”祖名股份(003030.SZ)成功实现扭亏为盈。...
特朗普提名“自己人”沃什执掌美... 据新华社报道,当地时间1月30日,美国总统特朗普通过社交媒体宣布,提名美国联邦储备委员会前理事凯文·...
爱芯元智将上市:连年大额亏损,... 撰稿|多客 来源|贝多商业&贝多财经 1月30日,爱芯元智半导体股份有限公司(下称“爱芯元智”,HK...
一夜之间,10只A股拉响警报:... 【导读】深康佳A等10家公司昨夜拉响退市警报 中国基金报记者 夏天 1月30日晚间,A股市场迎来一波...
谁在操控淳厚基金?左季庆为谁趟... 2026年1月6日,证监会一纸批复核准上海长宁国有资产经营投资有限公司(下称“长宁国资”)成为淳厚基...
工商银行党委副书记、行长刘珺会... 人民财讯1月31日电,1月29日,工商银行党委副书记、行长刘珺会见来访的上海电气集团党委书记、董事长...
布米普特拉北京投资基金管理有限... 从亚马逊到联合包裹,一场席卷美国企业的“瘦身”行动正在持续。多家企业近期承认,近年来的扩张步伐迈得过...
酒价内参1月31日价格发布 飞... 来源:酒业内参 新浪财经“酒价内参”过去24小时收集的数据显示,中国白酒市场十大单品的终端零售均价在...
筹码集中的绩优滞涨热门赛道股出... 2025年以来,在受多重因素的刺激下,科技、航天、基础化工等热门赛道中走出轮番上涨的结构性行情,其中...
2026年A股上市公司退市潮开... 来源:界面新闻 界面新闻记者 赵阳戈 随着2026年序幕拉开,A股市场新一轮“出清”即将上演。...
雷军官宣新直播:走进小米汽车工... 【太平洋科技快讯】1 月 31 日消息,小米创办人、董事长兼 CEO 雷军在社交媒体发文宣布,将于 ...
现货黄金直线跳水,跌破5200... 新闻荐读 1月29日晚,现货黄金白银快速走低,回吐盘中全部涨幅。23:15左右,现货黄金跌破5300...
加拿大拟与多国联合设立国防银行 新华社北京1月31日电 加拿大财政部长商鹏飞1月30日说,加拿大将在未来数月与国际伙伴密切合作,推进...
马斯克大消息!SpaceX申请... 据券商中国,美东时间1月30日,路透社报道,据两位知情人士透露,马斯克旗下SpaceX公司2025年...
澳网:雷巴金娜2-1萨巴伦卡女... 北京时间1月31日,2026赛季网球大满贯澳大利亚公开赛继续进行,在女单决赛中,5号种子雷巴金娜6-...
春节前白酒促销热:“扫码抽黄金... 春节临近,白酒市场再现价格异动。 近日,飞天茅台批价拉升,有酒商直言“年前要冲2000元关口”,引发...