js非同期入門から放棄(四)-Generatorパッケージ非同期タスク
4314 ワード
前の記事では、従来の非同期の実現方法を紹介していますが、ここではES 6の新たな非同期スキームであるGenerator関数を紹介します.
generator概要
簡単にgeneratorの原理と文法を紹介します.
基本文法
簡単な例で
データのインタラクションとは、現在実行されている結果をyieldを通じて伝えることができます.また、nextを使って外部パラメータを導入することもできます.
非同期タスクパッケージ
まず、非同期タスクの特徴と前文で述べたgenrator関数の特性を結合して、generatorを用いて非同期的な操作をパッケージ化する核心的な考えを抽出する.は、非同期タスクの実行時に、 を引き渡す.は、非同期タスクが終了した後、 を返納する.
スタートをきる
一番簡単な例から始めます.
しかし、上の第3部分は実行コードに関しては非常に柔軟ではないので、毎回このように書いてはいけません.したがって、次の目標はタスク実行器を実現することです.
自動タスク実行器
同じように、まず核心の考えを考えます.ある
締め括りをつける
本論文では、非同期タスクを
再度強調しました.
generator概要
簡単にgeneratorの原理と文法を紹介します.
基本文法
簡単な例で
generator
関数を知る.function* MyGenerator() {
yield 'yield : , '
yield ' next '
return ' return ,done true'
}
const gen = MyGenerator() // , next
console.log(gen.next()) // {value: "yield : , “, done: false}
console.log(gen.next())// {value: " next ", done: false}
console.log(gen.next())// {value: " return ,done true", done: true}
データ・インタラクションデータのインタラクションとは、現在実行されている結果をyieldを通じて伝えることができます.また、nextを使って外部パラメータを導入することもできます.
function* MyGenerator(){
const result = yield ' '
return result
}
const gen = MyGenerator()
console.log(gen.next())// generatorAndAsync2.html:19 {value: " ", done: false}
console.log(gen.next(' '))// {value: " ", done: true}
インタラクションのパラメータタイプはもちろん、関数であってもよい. function sayHi(){
console.log('hi');
}
function* MyGenerator(){
const result = yield sayHi()
return
}
const gen = MyGenerator()
const result = gen.next()// {value: sayHi, done: false}
result.value() // 'hi'
上記の最も核心的な二つの特性を備えた後、GEneratorは非同期操作でパッケージ化することができます.非同期タスクパッケージ
まず、非同期タスクの特徴と前文で述べたgenrator関数の特性を結合して、generatorを用いて非同期的な操作をパッケージ化する核心的な考えを抽出する.
yield
を使用して実行権next
を使用して実行権スタートをきる
一番簡単な例から始めます.
// 1. ,
function asyncTask(callback){
setTimeout(()=>{
callback('Hello Leo')
}, 1000)
}
// 2.
function* runTask() {
let text = yield asyncTask
console.log(text) // Hello Leo
}
// 3.
const gen = runTask()//
gen.next().value(function (text) {// asyncTask callback , callback next
gen.next(text)
})
まず、このコードは粗いが、generator
を使用して非同期タスクをカプセル化するというコア思想を反映している.最も直観的な利益は:runTask
の内容は同期コードのように見えます.しかし、上の第3部分は実行コードに関しては非常に柔軟ではないので、毎回このように書いてはいけません.したがって、次の目標はタスク実行器を実現することです.
自動タスク実行器
同じように、まず核心の考えを考えます.ある
generator
関数を自動的に実行させるには、while
サイクルだけです.1. yield done true, ;
2. yield done false, , next,
分析に基づいて以下のアクチュエータを実現します.function autoExecute(task) {
const gen = task()
let result = gen.next()
while(true){
if(result.done){
break //
return
}
console.log(result.value)// console.log
result = gen.next(result.value) // result
}
}
function* simpleTask(){
yield 1
yield 2
yield 3
return
}
autoExecute(simpleTask)// 123
上のアクチュエータは既に原形を持っていますが、前の例では、reult.valueが関数である場合はまだ処理されていません.function isFunction(source){
return Object.prototype.toString.call(source) === "[object Function]"
}
function autoExecute(task) {
const gen = task()
let result = gen.next()
let isRuningAsync = false // ,
while (!isRuningAsync) {
if (result.done) {
return
}
console.log(result.value)
/* start */
if (isFunction(result.value)) {
isRuningAsync = true
const callback = (arg) => {
result = gen.next(arg) //
isRuningAsync = false
}
result.value(callback)
/* end */
} else {
result = gen.next(result.value)
}
}
}
autoExecute(runTask) //
上のこの自動アクチュエータは、GEneratorの非同期タスクのパッケージを完成しました.締め括りをつける
本論文では、非同期タスクを
generator
関数でカプセル化する方法を説明することにより、非同期コードの作成をより明確にすることができます.再度強調しました.
generator
関数で非同期タスクをカプセル化する思想は明確です.Generator関数の流れを制御し、適切なタイミングでプログラムの実行権を受信し、返却します.しかし、具体的な実現方法は唯一ではありません.例えば、本稿では最も簡単で直接的なコールバック関数方式を使って、阮一峰先生の『es 6入門』教程で、thunkの考え方を使って説明する部分もあります.自分で調べられます.