ES 6を利用したgenerators化は同期となります.


generatorは非同期を同期に変えて、JSの嫌なリターンをはっきりさせることができます.
以下の例:
var fs = require('fs')

function run(generator){

  console.log('now in run')

  var it = generator(go)

  console.log(`now get it : ${it}`)

  function go(err,result){
    console.log(`now in go, err is 
      ${err},result is 
      ${result}`)

    var next = it.next(result)

    console.log(`now after it.next and its value and done : ${next.value},${next.done}`)
  }

  go()

  console.log(`end of function run`)

}

run(function* (done){

  console.log(`before var exercises`)

  var exercises = yield fs.readFile('gulp.js',done)

  console.log(`exercises is ${exercises}`)

})
コンサート・ソロでの結果はこうです.
now in run
now get it : [object Generator]
now in go, err is 
      undefined,result is 
      undefined
before var exercises
now after it.next and its value and done : undefined,false
end of function run
now in go, err is 
      null,result is 
      var gulp= require('gulp');
var htmlmin=require('html-minifier');

gulp.task('minifyhtml',function(){

    gulp.src('myjq.html')
    .pipe(htmlmin({collapseWhitespace:true}))
    .pipe(gulo.dest('./dist'))
})
exercises is var gulp= require('gulp');
var htmlmin=require('html-minifier');

gulp.task('minifyhtml',function(){

    gulp.src('myjq.html')
    .pipe(htmlmin({collapseWhitespace:true}))
    .pipe(gulo.dest('./dist'))
})
now after it.next and its value and done : undefined,true
鍵はこのrun関数です.実行プロセスはこうです.
  • 新しいgenerator-i teratorオブジェクト(it)
  • go関数を定義し、go関数でit.next
  • を呼び出しました.
  • go関数をgentrator-teratorオブジェクトに転送しました.
  • は、go関数をパラメータなしに一回実行して、generator
  • を初期化する.
    go関数は全部で二回実行されました.一回はパラメータを持たないで、二回目はyield fsの結果を得て次のことをします.
    fs.readFileを別の関数に包装してから見ることもできます.
    function run(taskdef){
    
      let task = taskdef()
    
      let next = task.next()
    
      console.log(`  run   next,${next.value}`)
    
      function step(){
    
        console.log('in step')
    
        if(!next.done){
    
          if(typeof next.value === 'function'){
    
            console.log(`type func`,next.value)
    
            next.value( function(err,data){
    
              if(err){
    
                console.error('err happend', err)
    
                task.throw(err)
    
                return
              }
    
              console.log('data happed',data)
    
              next = task.next(data)
    
              console.log(`next= task.next(data),${next.value},${next.done}`)
    
              step()
    
    
            })
          }
    
          else{ // else          
    
            console.log(`now value not func, ${next.value}`)
    
            next = task.next(  next.value )
    
            console.log(`in else module , nextvalue = ${next.value}`)
    
            step()
    
          }
        }
    
      }
    
    
      step()
    
    }
    
    let fs = require('fs')
    
    function readFile(filename){
    
      return function(callback){
    
        fs.readFile(filename,callback)
      }
    
    }
    
    run(function* (){
    
      let contents = yield readFile('gulp.js')
    
      console.log(`contents happed ,${contents}`)
    
      console.log('done')
    })
    
    コンサートソロステージの結果は:
      run   next,function (callback){
    
        fs.readFile(filename,callback)
      }
    in step
    type func function (callback){
    
        fs.readFile(filename,callback)
      }
    data happed 76 61 72 20 67 75 6c 70 3d 20 72 65 71 75 69 72 65 28 27 67 75 6c 70 27 29 3b 0a 76 61 72 20 68 74 6d 6c 6d 69 6e 3d 72 65 71 75 69 72 65 28 27 68 74 ... >
    contents happed ,var gulp= require('gulp');
    var htmlmin=require('html-minifier');
    
    gulp.task('minifyhtml',function(){
    
        gulp.src('myjq.html')
        .pipe(htmlmin({collapseWhitespace:true}))
        .pipe(gulo.dest('./dist'))
    })
    done
    next= task.next(data),undefined,true
    in step
    
    これはよく分かりませんので、自分でコードを押してみてください.
    そしてプロミを合わせて使うこともできます.とにかくいい感じです.