blog

15分で非同期ソリューションを理解する

はシングルスレッドです; ブラウザはマルチスレッドです; すべての非同期ソリューションは最終的にコールバックです。 互いに依存する複数のリクエストを扱う場合、promiseのthenメソッドは面倒す...

Jul 29, 2020 · 4 min. read
シェア

はじめに

javascriptはシングルスレッド、ブラウザはマルチスレッド、すべての非同期ソリューションは最終的にコールバックです。

プロミスの基本的な使い方と本質

let p1 = new Promise((resolve, reject) => {
 let arr = [1,2,3,4,5];
 let arr1 = arr.filter(item => item > 3);
 setTimeout(() => {
 resolve(arr1);
 }, 1000)
})
p1.then(res => {
 console.log(res);
},err => {
 console.log(err);
})
  • つまり、pending->resolve(満たされた状態)か、pending->rejected(拒否された状態)のどちらかしか変化しません;

  • このメソッドは、2つの変化した状態に対応する2つのパラメーターと

その後チェーンコール

const p1 = new Promise((resolve, reject) => {
 let arr = [1,2,3,4,5];
 let arr1 = arr.filter(item => item > 3);
 setTimeout(() => {
 resolve(arr1);
 }, 1000)
})
p1
 .then(res => {
 console.log(res)
 //thenコールバックはプロミスを返すことができる。
 return new Promise((resolve, reject) => {
 let arr2 = [1,2,3];
 setTimeout(() => {
 resolve(arr2)
 }, 1000);
 })
 })
 .then(res => {
 console.log(res)
 //thenコールバックで値を返すこともできる。
 return 1
 })
 .then(res => {
 console.log(res)
 })
//
//[4,5];
//[1,2,3];
//1

async/awaitの基本的な使い方

互いに依存し合う複数のリクエストを扱う場合、promiseのthenメソッドは面倒で、async/awaitは軽量です。

使い方:

  • 関数の前に async を追加すると、関数の実行後に自動的に Promise オブジェクトが返されます。
//eg1 
async function Person() {
 
}
let result = Person()
console.log(result);
//Personメソッドは戻り値を持たないが、結果はPromiseオブジェクトとして出力される。
//Promise {<resolved>: undefined}
//->__proto__: Promise
//->[[PromiseStatus]]: "resolved"
//->[[PromiseValue]]: undefined
//eg2:
async function Person() {
 return 2
}
let result = Person()
console.log(result);// Promise {<resolved>: 2}
//Promise {<resolved>: 2}
//->__proto__: Promise
//->[[PromiseStatus]]: "resolved"
//->[[PromiseValue]]: 2
  • aitは単独ではなく、非同期関数の内部で使用する必要があります。
async function Person() {
 let result = await Promise.resolve('success')
 console.log(result)
}
Person()
  • awaitはPromiseオブジェクトに従う必要があり、そうでなければ意味がありません。
function ret() {
 return new Promise((resolve, reject) => {
 setTimeout(() => {
 resolve('success')
 })
 })
}
async function test() {
 let result = await ret() //fnはPromiseオブジェクトを返すので
 console.log(result) //ここでは、promiseが成功した後に渡されるコードをタイプアウトする。'success'
}
test()

非同期/待機エラー処理

エラー処理に関しては、awaitはPromiseの成功状態をパラメータとして受け取るので、エラーをキャッチするためにtry catchが必要です。

function ret (num){
 return new Promise((resolve, reject) => {
 setTimeout(() => {
 if (num >= 100) {
 resolve('success')
 } else {
 reject('failed')
 } 
 }, 1000)
	})
}
async function test() {
 let result = await ret(222)
 return result //awaitはPromiseの成功ステータスを受け付けるので、失敗するとcatchに飛ぶ。
}
test().then(response => {
 console.log(response) 
}).catch(error => {
 console.log(error)
})

async/await

非同期関数の中でawaitを使うと、awaitの中のコードは同期的で、awaitの後のPrimiseコードが実行し終わるのを待つだけで、次の行に進むことができます。

function fn(name) {
 return new Promise((resolve, reject) => {
 setTimeout(() => {
 resolve(`${name}成功`)
 }, 1000)
 })
}
async function test() {
 let p1 = await fn(' ')
 let p2 = await fn('小明')
 let p3 = await fn(' ')
 return [p1, p2, p3]
}
test().then(result => {
 console.log(result)
}).catch(result => {
 console.log(result)
})

Demo

約束

function request(time) {
 return new Promise((resolve, reject) => {
 setTimeout(() => {
 resolve(time)
 }, time)
 })
}
request(500).then(result => {
 return request(result + 1000)
}).then(result => {
 return request(result + 1000)
}).then(result => {
 console.log(result)
}).catch(error => {
 console.log(error)
}) 

async/awaitへの変換

function request(time) {
 return new Promise((resolve, reject) => {
 setTimeout(() => {
 resolve(time)
 }, time)
 })
}
async function getResult() {
 let p1 = await request(500)
 let p2 = await request(p1 + 1000)
 let p3 = await request(p2 + 1000)
 return p3
}
getResult().then(result => {
 console.log(result)
}).catch(error => {
 console.log(error)
})
Read next

アンチジッターとスロットリングの機能紹介

一般的な言い方をすると、ユーザーが頻繁にトリガーする場合、頻繁に実行する間隔時間を設定するために1つのイベントしか実行できないということです。 アイデア:間隔時間500ミリ秒を設定し、最初のクリックは、実装の直後に、500ミリ秒を待って、2番目のトリガー内の500ミリ秒を観察していない場合、頻繁にクリックすると、2回目のトリガーされた場合、関数の実装に移動しないでください...

Jul 28, 2020 · 4 min read