1.約束とは
- 主に非同期計算に使用されます
- 非同期操作はキューに入れられ、希望の順序で実行され、期待に応える結果を返すことができます
- オブジェクト間でpromiseを渡したり操作したりできるため、キューの処理に役立ちます
2.非同期コールバックの問題:
- 以前の非同期処理は、純粋なコールバック関数の形式で処理されていました。
- コールバック地獄に入るのは簡単で、戻る能力の機能を奪います
- 問題は解決できますが、読み、維持するのは困難です
- 少しの不注意は、コールバック地獄につながります-深い入れ子レベル、維持するのが難しい
3.約束の紹介
- promiseはオブジェクトです。オブジェクトと関数の違いは、オブジェクトは状態を保存できますが、関数は保存できないことです(クロージャを除く)
- 戻る機能の機能を奪うことはないので、データを取得するためにコールバックをレイヤーごとに渡す必要はありません。
- コードスタイル、理解しやすく、保守しやすい
- 複数の非同期待機の統合は簡単に解決できます
4.詳細な約束
resolveの役割は、Promiseオブジェクトの状態を「unfinished」から「success」(つまり、保留中からresolved)に変更し、非同期操作が成功したときに呼び出し、非同期操作の結果をパラメーターとして渡すことです。
拒否の役割は、Promiseオブジェクトの状態を「未完了」から「失敗」(つまり、保留中から拒否)に変更し、非同期操作が失敗したときに呼び出し、非同期操作によって報告されたエラーをパラメーターとして渡します。 。
約束には3つの状態があります。
- 保留中[未定]初期状態
- 実行された[実行された]操作が成功しました
- 拒否[拒否]操作に失敗しました
場合約束状態変化、**における応答関数次いで()**以降のステップを処理するようにトリガされ、一度
約束状態の変更は、変更されません。
Promiseオブジェクトの状態が変化する可能性は2つだけです。
- 保留中から実行済みに変更
- 保留中から拒否に変更します。
これらの2つの状況が発生する限り、状態は凍結され、それ以上変化しません。
5、.then()
- 実行済み(成功)と拒否済み(失敗)を表す2つの関数をパラメーターとして受け取ります
- .then()は新しいPromiseインスタンスを返すので、チェーンすることができます
- 現在のPromise状態が変化すると、.then()は特定の状態応答関数を選択して、その最終状態に従って実行します。
- ステータス応答関数は、新しいpromiseまたは他の値を返すことができます。または、値を返さない場合は、nullを返すと見なすことができます。
- 新しいpromiseが返された場合、新しいpromiseの状態が変更された後、次のレベルの.then()が実行されます。
- 他の値が返された場合、次のレベルがすぐに実行されます。then()
6.エラー処理の2つの方法:
Promiseは自動的に内部例外をキャッチし、処理のために拒否された応答関数に渡します。
(1)最初のエラー処理
<script>
new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('bye')
},2000)
}).then((val)=>{
console.log(val)
},(err)=>{
console.log("Error",error)
})
</script>
(2)2番目のタイプのエラー処理
<script>
new Promise((resolve)=>{
setTimeout(()=>{
throw new Error('bye')
},2000)
}).then((val)=>{
console.log(val)
}).catch(error=>{
console.log("Error",error)
})
</script>
第一种:reject('错误信息').then(() => {}, () => {错误处理逻辑})
第二种:throw new Error('错误信息').catch( () => {错误处理逻辑})
2番目の方法を使用することをお勧めします。これは、より明確で読みやすく、以前のすべてのエラーをキャプチャできます(Nをキャプチャしてからコールバックエラーをキャプチャできます)。
7、約束の使用法
(1)一般的な使用法:
非同期操作とタイマーが組み合わされます。タイマーが最初にトリガーされた場合、それはタイムアウトと見なされ、ユーザーに通知されます。
例如:我们要从远程的服务家在资源如果5000ms还没有加载过来我们就告知用户加载失败
(2)実際の使用法
コールバックはPromiseとしてパッケージ化されており、2つの明らかな利点があります。
- 読みやすさ
- 返された結果は、任意のPromiseキューに追加できます
8.コールバック地獄と約束の比較
(1)コールバック地獄
/***
第一步:找到北京的id
第二步:根据北京的id -> 找到北京公司的id
第三步:根据北京公司的id -> 找到北京公司的详情
目的:模拟链式调用、回调地狱
***/
// 回调地狱
// 请求第一个API: 地址在北京的公司的id
$.ajax({
url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/city',
success (resCity) {
let findCityId = resCity.filter(item => {
if (item.id == 'c1') {
return item
}
})[0].id
$.ajax({
// 请求第二个API: 根据上一个返回的在北京公司的id “findCityId”,找到北京公司的第一家公司的id
url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/position-list',
success (resPosition) {
let findPostionId = resPosition.filter(item => {
if(item.cityId == findCityId) {
return item
}
})[0].id
// 请求第三个API: 根据上一个API的id(findPostionId)找到具体公司,然后返回公司详情
$.ajax({
url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/company',
success (resCom) {
let comInfo = resCom.filter(item => {
if (findPostionId == item.id) {
return item
}
})[0]
console.log(comInfo)
}
})
}
})
}
})
(2)約束の書き方
// Promise 写法
// 第一步:获取城市列表
const cityList = new Promise((resolve, reject) => {
$.ajax({
url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/city',
success (res) {
resolve(res)
}
})
})
// 第二步:找到城市是北京的id
cityList.then(res => {
let findCityId = res.filter(item => {
if (item.id == 'c1') {
return item
}
})[0].id
findCompanyId().then(res => {
// 第三步(2):根据北京的id -> 找到北京公司的id
let findPostionId = res.filter(item => {
if(item.cityId == findCityId) {
return item
}
})[0].id
// 第四步(2):传入公司的id
companyInfo(findPostionId)
})
})
// 第三步(1):根据北京的id -> 找到北京公司的id
function findCompanyId () {
let aaa = new Promise((resolve, reject) => {
$.ajax({
url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/position-list',
success (res) {
resolve(res)
}
})
})
return aaa
}
// 第四步:根据上一个API的id(findPostionId)找到具体公司,然后返回公司详情
function companyInfo (id) {
let companyList = new Promise((resolve, reject) => {
$.ajax({
url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/company',
success (res) {
let comInfo = res.filter(item => {
if (id == item.id) {
return item
}
})[0]
console.log(comInfo)
}
})
})
}