2016-07-31 5 views
3

で働いていない待つforEachは非同期/ forEachの

export let appState = observable({ 
     bunny : [] 
    }); 

    appState.loadBunny = async function(bugs) { 
    bugs.forEach(function(data) { 
     let temp = {}; 
     temp['id'] = data.id; 
     temp['site_url'] = data.site_url; 
     temp['email'] = await decrypt(sessionStorage.getItem('key'), data.email); 
     temp['username'] = await decrypt(sessionStorage.getItem('key'), data.username); 
     temp['password'] = await decrypt(sessionStorage.getItem('key'), data.password); 
     temp['note'] = await decrypt(sessionStorage.getItem('key'), data.note); 
     temp['tag'] = await decrypt(sessionStorage.getItem('key'), data.tag); 
     temp['created_at'] = data.created_at; 
     temp['updated_at'] = data.updated_at; 
     runInAction("update state after decrypting data",() => { 
      this.bunny.push(temp); 
     }); 

    }); 
}; 

    appState.fetch = async function() { 
     let xoxo = await axios.get('/api/vault/', { 
      headers: {'Authorization': "JWT " + sessionStorage.getItem('token')} 
     }); 
     this.loadBunny(xoxo.data); 
    } 

、ここで非同期/のawaitを使用しようとすると、エラーされたときに予期しないトークンを取得します。

ERROR in ./static/apps/store/passwords.js 
Module build failed: SyntaxError: ...static/apps/store/passwords.js: Unexpected token (15:30) 
    13 |   temp['id'] = data.id; 
    14 |   temp['site_url'] = data.site_url; 
> 15 |   temp['email'] = await decrypt(sessionStorage.getItem('key'), data.email); 
    |        ^
    16 |   temp['username'] = await decrypt(sessionStorage.getItem('key'), data.username); 
+0

'async'関数でのみ' await'することができます。 – zerkms

答えて

3

awaitは、async関数で使用され、通常の関数であるforEachコールバックで使用されます。

forEachコールバックとしてasync機能が提供されても、forEachは何も返さないため、約束を得ることができません。

これを行うには、プロミスチェーンを手動で作成する必要があります。

appState.loadBunny = async function(bugs) { 
    let promise = Promise.resolve(); 

    bugs.forEach(function(data) { 
     promise = promise.then(async function() { 
     let temp = {}; 
     ... 
     }); 
    }); 

    await promise; 
    } 

これはfor...ofasync機能に不可欠である理由です:

appState.loadBunny = async function(bugs) { 
    for (const data of bugs) { 
     let temp = {}; 
     ... 
    }); 
    } 

ジェネレータ機能とyieldこのような場合には同様に振る舞います。

+0

実際、 'forEach'は何も返しません。 – Bergi

+0

@Bergi確かに、それに気づいてくれてありがとう。 – estus

3

awaitだけasync関数内で動作しますが、このように:

async function test() { 
    await myObj.setObj(2, 3); 

    console.log(obj.a + obj.b); 
} 

test(); 

このように、リファクタリングする必要がありますあなたのコードそのようなawait decrypt(sessionStorage.getItem('key'), data.email呼び出しは、独自のasync関数内にあります。