Movatterモバイル変換


[0]ホーム

URL:


JS.next

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

この広告は、90日以上更新していないブログに表示しています。

async関数が実装された

概要

非同期な処理を同期的に書ける関数タイプが実装された。


基本

「async」キーワードに続けて関数定義を書くと、async関数となる。

asyncfunction afn1(){}afn2 = async () =>{}obj ={   async afn3(){}}


async関数を呼び出すとプロミスが返される。

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


このプロミスは、async関数が終了するとその返り値で解決され、例外が起こると棄却される。

asyncfunction afn4( flag ){if ( flag )return'Yes'elsethrow'No'}afn4(true  ).then(  v => console.log( v ) )/// "Yes"afn4(false ).catch( v => console.log( v ) )/// "No"


ちなみに返り値にプロミスを返すと、その解決を待ってからその解決値をもってasync関数が返すプロミスは解決される。

asyncfunction afn5(){return Promise.resolve( 123 )}afn5().then( v => console.log( v ) )/// 123


await式

await式はキーワード「await」とプロミス型値「p」を使って、「await p」の形で書くことが出来る。
await式は「p」(プロミスでなくともプロミスとしてラップされる)が解決するまで待ってその解決値を式結果として返す。

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


async関数もプロミスを返すので、async関数の処理の待ち合いにも使える。

asyncfunction afn7(){for (let i = 0; i < 3; i++ ){    await afn6()}}afn7()/// "スタート"  →  "1秒経ったよ!"  →/// "スタート"  →  "1秒経ったよ!"  →/// "スタート"  →  "1秒経ったよ!"


つまり、プロミスを返す関数を利用するのにasync関数が良く使え、
async関数を利用するのにasync関数が良く使える。


応用

プロミスを返すWebAPIを良く扱う

例:キャッシュからファイルを返す関数 もし無ければフェッチしてファイルを取ってきてキャッシュに追加する
いままで:

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 )returnnew 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関数を使うと:

asyncfunction 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 = 1const 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 = 1const ary =[ p, q]while ( ary.length < size ){[ p, q] =[ q, p + q]     ary.push( q )     yield}return ary}
function calcFibAryAsync( size ){returnnew 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 ) )

効率よくシンプルで美しく書くのが難しい。


async関数とrequestIdleCallbackを使うと:

asyncfunction calcFibAryAsync( size ){let p = 1, q = 1const 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 ) )

固まらず、スマートに書ける。


実装されるバージョン

V85.2.328

検索
最新V8の全試験機能を有効にするためのフラグ

--harmony --harmony_do_expressions --harmony_class_fields --harmony_static_fields

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp