JS.next

JavaScriptの最新実装情報を追うブログ

async関数が実装された

概要






asyncasync
async function afn1() { }

afn2 = async () => { }

obj = { 
  async afn3() { }
}


async
console.log( afn1() )  // <Promise>


async
async function afn4( flag ) {
  if ( flag ) return 'Yes'
  else throw 'No'
}

afn4( true  ).then(  v => console.log(v) )  /// "Yes"
afn4( false ).catch( v => console.log(v) )  /// "No"


async
async function afn5() {
  return Promise.resolve( 123 )
}

afn5().then( v => console.log(v) )  /// 123


await


awaitawaitp使await p
awaitp
function delay(s) {  // s秒後に解決するプロミスを返す関数
  return new Promise( ok => setTimeout( ok, s, `${s}秒経ったよ!` ) )
}
async function afn6() {
  console.log( 'スタート' )
  let message = await delay(1)
  console.log( message )
}

afn6()
  /// "スタート"  →  "1秒経ったよ!"



asyncasync使
async function afn7() {
  for ( let i = 0; i < 3; i++ ) {
    await afn6()
  }
}

afn7()
  /// "スタート"  →  "1秒経ったよ!"  →
  /// "スタート"  →  "1秒経ったよ!"  →
  /// "スタート"  →  "1秒経ったよ!"


async使
asyncasync使


Web API


 

function getTextFile( url ) {
  return caches.open( 'test' ).then( 
    cache => cache.match( url ).then(
      response => {
         if ( !response ) {
           return fetch( url ).then(
             response => cache.put( url, response )
           ).then(
             () => getTextFile( url )
           )
         }
         return response.text()          
      }
    )
  ) 
}

getTextFile( '' ).then( t => console.dir(t) )





function spawn( gfn ) {
  return ( ...args ) => {
    const gen = gfn( ...args )
    return new Promise( ( resolve, reject ) => {
      const step = v => {
        const { value, done } = gen.next(v)
        Promise.resolve( value ).then( done ? resolve : step ).catch( reject )
      }
      step()
    } )
  }
}
getTextFile = spawn( function* ( url ) {
  const cache = yield caches.open( 'test' )  
  const response = yield cache.match( url )  
  if ( !response ) {
    yield cache.put( url, yield fetch( url ) )
    return yield getTextFile( url )
  }
  return response.text()
})

getTextFile( '' ).then( t => console.dir(t) )




async使
async function getTextFile( url ) {
  const cache = await caches.open( 'test' )  
  const response = await cache.match( url )  
  if ( !response ) {
    await cache.put( url, await fetch( url ) )
    return await getTextFile( url )
  }
  return response.text()
}

getTextFile( '' ).then( t => console.dir(t) )




使




function calcFibAry( size ) {
  let p = 1, q = 1
  const ary = [ p, q ]   
  while ( ary.length < size ) {
     [ p, q ] = [ q, p + q ]
     ary.push(q)
  }
  return ary
}

console.log( calcFibAry( 1e7 ) )




requestIdleCallback使
function *calcFibAryStep( size ) {
  let p = 1, q = 1
  const ary = [ p, q ]   
  while ( ary.length < size ) {
     [ p, q ] = [ q, p + q ]
     ary.push(q)
     yield
  }
  return ary
}
function calcFibAryAsync( size ) {  
  return new Promise( resolve => {
    const step = calcFibAryStep( size )
    const proceed = deadline => {
      do {
        const { value, done } = step.next()
        if ( done ) resolve( value )
      } while ( deadline.timeRemaining() > 0 )
      requestIdleCallback( proceed )
    }
    requestIdleCallback( proceed )
  } )  
}

calcFibAryAsync( 1e7 ).then( a => console.log(a) )




asyncrequestIdleCallback使
async function calcFibAryAsync( size ) {
  let p = 1, q = 1
  const ary = [ p, q ] 
  const waitUntilIdle = () => new Promise( ok => requestIdleCallback(ok) )
  let deadline = await waitUntilIdle()  
  while ( ary.length < size ) {
     [ p, q ] = [ q, p + q ]
     ary.push(q)
     if ( deadline.timeRemaining() == 0 ) deadline = await waitUntilIdle()
  }
  return ary
}

calcFibAryAsync( 1e7 ).then( a => console.log(a) )





V8 5.2.328