2017-09-26 5 views
0

以下、配列の値をローカル変数に代入しようとしています。私はその値を取得する配列を返す関数を呼び出しています。問題は、2番目の関数のPromisesが、配列が呼び出し元に返されるまで解決されないということです。私はretArrayPromise.all()を使用しようとしましたが、それは私のために決して働きません。私がconsole.log()私のsomeobjectオブジェクトの場合、SkywalkerTitles()への呼び出しが空の配列を返すので、arrOfTitlesフィールドは決して印刷されません。Promise.all()を使用して関数内に構築されている配列を返すのを延期するにはどうすればよいですか?

コードhereを実行できます。

someObject.arrOfTitlesタイトルの配列を取得するにはどうすればSkywalkerTitles()

function SkywalkerTitles(){ 
    let retArray = []; 

    fetch('https://swapi.co/api/people/') 
    .then(function(response){ 
    response.json() 
    .then(function(result){ 
     return result.results[0]; 
    }) 
    .then(function(result){ 
     result.films.forEach(function(film){ 
     fetch(film) 
     .then(function(response){ 
      response.json().then(function(result){ 
      console.log(result.title); 
      retArray.push(result.title); 
      }); 
     }); 
     }) 
     .catch(function(error){ 
     console.log(error) 
     }); 
    }); 
    }) 
    .catch(function(error){ 
    console.log(error) 
    }); 

} 

function UseReturnedArray() { 
    let someObject = { aThing: '', anotherThing: '', arrOfTitles: null }; 

    someObject.aThing = 'Thing One'; 
    someObject.anotherThing = 'Thing Two'; 
    someObject.arrOfTitles = SkywalkerTitles(); 

    console.log('Object With Returned Array:\n\n', JSON.stringify(someObject, null, 2)); 
} 

UseReturnedArray(); 
+1

の使用に比べて平坦化された方法のみシングルキャッチ、ほとんどの場合、これまで必要

function SkywalkerTitles() { return fetch('https://swapi.co/api/people/').then(function (response) { return response.json(); }).then(function (result) { return result.results[0]; }).then(function (result) { return Promise.all(result.films.map(function (film) { return fetch(film).then(function (response) { return response.json(); }).then(function (result) { return result.title; }); })); }); } function UseReturnedArray() { SkywalkerTitles().then(function (arrOfTitles) { var someObject = { aThing: '', anotherThing: '', arrOfTitles: arrOfTitles }; console.log('Object With Returned Array:\n\n', JSON.stringify(someObject, null, 2)); }).catch(function(reason) { console.log(reason); }); } UseReturnedArray(); 

注意あなたがまだやっていない関数から約束を返せば、 'SkywalkerTitles()。then(result => someObject.arrOfTitles = result)'のようになります。 [非同期呼び出しからの応答を返すにはどうすればいいですか?](https://stackoverflow.com/q/14220321/218196) –

+0

'SkywalkerTitles'は何も返さないので、 someObject.arrOfTitles'は 'undefined'になります。また、' SkywalkerTitles'は非同期コンポーネントを持っているので、 'someObject.arrOfTitles'はこれまでと同じことが可能な唯一のものは約束オブジェクトです –

答えて

1

あなたの環境がまだ非同期/待機をサポートしていない場合でも、@Svenskungankaの回答は完全で価値があります。また、あなたはすでにPromisesに部分的に精通しているので、コードは、外国見てはいけない:P

はあなたの主な問題は、SkywalkerTitlesが実際にあなたが、それは空の配列を返すと主張(何も返さない、それは実際にはreturn文を持っていないということですので、返される値はundefined

です

.catchコードも削除しました。なぜなら、実際に問題が発生していた場所でコードが拒否反応を処理しているためですデータが実際に有効であるとコードが期待するチェーンを所有しています!約束は正しくそうでない配列(に解決された場合の約束チェーンはあなたの、そしてArray#map代わりのArray#forEach + Array#push

+0

その古い学校の入れ子..:しかし、プロミスの仕組みについては100%良い例です。 –

+0

実際には "babeljs"が入れ子になっています:p –

+0

ありがとうございました@JaromandaX ..この作業だけでなく、あなたの説明が私に約束事で起こっていることを理解するのに役立ちます。SkywalkerTitles()の返事は、Promise.all()と何らかの形で連動していると思っていたので、私は必要だったと思ったので、Promise.all()とサンプルコードから戻りました。素晴らしい答えにもう一度感謝します。 – SethD

1

あなたは本当にあなたのコードはかなりをクリーンアップし、より分かりやすく可能性がある、のawait /非同期を活用する必要があります。これはへの外国人に見える場合

async function SkywalkerTitles() { 
    let character = await fetch('https://swapi.co/api/people/').then(res => res.json()).then(res => res.results[0]) 
    return await Promise.all(character.films.map(async (film) => { 
    return await fetch(film).then(res => res.json()).then(res => res.title) 
    })) 
} 

async function UseRetrunedArray() { 
    try { 
    let someObject = { 
     aThing: '', 
     anotherThing: '', 
     arrOfTitles: await SkywalkerTitles() 
    } 

    console.log(someObject) 
    } catch (e) { 
    console.error(e) 
    } 
} 

UseRetrunedArray() 

https://repl.it/Lc2f/2

を参照してください。あなたは、どのようにしてasync/awaitPromiseが一緒に動作するかを少しお読みになることをお勧めします。

+0

@Svenskungankaに感謝します。プロミスとの非同期/待機の仕組みを見ていきます。私がプロミスと仕事をするのがとても新しいので、この構文は私の周りを包み込むためにちょっとした時間がかかるかもしれません。感謝しますが、常に学ぶ機会を感謝します! – SethD

関連する問題