地獄の解決方法
18679 ワード
地獄は何ですか?
非同期のJavaScriptプログラム、またはコールバック関数を使ったJavaScriptプログラムは、直感的にスムーズに読まれにくく、大量のコードは以下のように終わります.簡単に言えば、関数がパラメータ層としてネストされているということです.コードはこのような形で展示されている時、私達が読むのに不便です.
1.分解function:各ステップを単一のfunctionに分解する
2.Promiseチェーンで呼び出す方式
3.Generator関数により実行を一時停止する効果方式
4.ES 8を通過する非同期関数async/await asyncはこれはasync関数です.awaitはこの関数の中でしか使えません. awaitはここでPromiseの戻りを待ってから、 を実行し続けると表しています. awaitに続いているのはPromiseオブジェクトです.もちろん、他の戻り値は大丈夫です.すぐ実行します. awaitが待っているのはPromiseオブジェクトですが、書く必要はありません.then()は、戻り値 を直接に得ることができます.
非同期のJavaScriptプログラム、またはコールバック関数を使ったJavaScriptプログラムは、直感的にスムーズに読まれにくく、大量のコードは以下のように終わります.簡単に言えば、関数がパラメータ層としてネストされているということです.コードはこのような形で展示されている時、私達が読むのに不便です.
setTimeout(function (name) {
var catList = name + ','
setTimeout(function (name) {
catList += name + ','
setTimeout(function (name) {
catList += name
console.log(catList)
}, 200, 'Lion')
}, 200, 'Jaguar')
}, 200, 'Panther')
// Panther,Janguar,Lion
解決コール地獄1.分解function:各ステップを単一のfunctionに分解する
function buildCatList(list, returnVal, fn) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
fn(catList)
}, 200, returnVal)
}
buildCatList('', 'Panther', getJanguar)
function getJanguar(list) {
buildCatList(list, 'Janguar', getLynx)
}
function getLynx(list) {
buildCatList(list, 'Lion', print)
}
function print(list) {
console.log(list)
}
// Panther,Janguar,Lion
タイマーにおけるコールバック関数は、外層関数の作用領域にあり、パラメータを通して入ってきたので、大域変数が発生せず、コードを重複していません.しかし、Functionの分割方法は、単にコードブロックを分割するだけで、後続のメンテナンスに不利になることがあります.2.Promiseチェーンで呼び出す方式
function buildCatList(list, returnVal) {
return new Promise(function (resolve, reject) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
resolve(catList)
}, 200, returnVal)
})
}
buildCatList('', 'Panther').then(function (res) {
return buildCatList(res, 'Janguar')
}).then(function (res) {
return buildCatList(res, 'Lion')
}).then(function (res) {
console.log(res)
})
// Panther,Janguar,Lion
前の地獄の書き方を変えましたが、基本的には関数がセットされていて、見た目はそんなに綺麗ではありません.3.Generator関数により実行を一時停止する効果方式
function getPanther(list) {
return list + 'Panther' + ','
}
function getJaguar(list) {
return list + 'Jaguar' + ','
}
function getLion(list) {
return list + 'Lion'
}
function* buildCatList() {
yield getPanther
yield getJaguar
yield getLion
}
//
function run(fn){
const gen = fn() // Generator , (Iterator)
var a = gen.next().value('') // next() , value done
var b = gen.next().value(a)
var c = gen.next().value(b)
console.log(c)
}
run(buildCatList) //
// Panther,Jaguar,Lion
はゲナートを通じてより良い文法構造を提供できますが、ゲナートとyieldの文脈はここでは多少適切ではありません.4.ES 8を通過する非同期関数async/await
function buildCatList(list, returnVal) {
return new Promise(function (resolve, reject) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
resolve(catList)
}, 200, returnVal)
})
}
function fn(list) {
return list + ',' + 555
}
async function render() {
var a = await buildCatList('','Panther')
var b = await buildCatList(a, 'Jaguar')
var c = await buildCatList(b, 'Lion')
var d = await fn(c)
console.log(d)
}
render()
// Panther,Jaguar,Lion,555
コードは簡潔で明瞭で、非同期コードも「同期」コードの構造を持っています.