イベントをトリガーしてデータを取得するReactコンポーネントがあります。これにより、データを取得するための動的な数のストアドプロシージャ呼び出しが発生し、各呼び出しのデータはまったく異なる場所に格納されます。それから、すべてのデータが受信されて利用可能になったら、再レンダリングする必要があります。
Axios呼び出しの数は動的であるため、次のように配列を作成してaxios.all
に挿入しています。
let promises = [];
for (let i = 0; i < requests.length; i++) {
promises.Push(axios.get(request[i].url, { params: {...} }));
}
axios.all(promises).then(/* use the data */);
問題は、各axiosリクエストがまったく異なる場所のオブジェクトに追加されるデータを返すことです。単一のthen
の正しい場所にそれらをすべて配置する方法がないので(どの応答がどの場所に行くのかをどのように知ることができますか?)、私はこのようなことを試みました:
let promises = [];
for (let i = 0; i < requests.length; i++) {
promises.Push(
axios.get(request[i].url, { params: {...} })
.then(response => {myObject[request[i].saveLocation] = response.data;})
);
}
axios.all(promises).then(/* use the data */);
しかし、これは期待どおりには機能しません。各then
の後のget
が実行されますが、axios.all
に接続されたthen
の十分後までは実行されません。私のコードはデータをオブジェクトに保存する前に使用しようとするため、これは明らかに問題です。
対応するプロミスが解決された後に実行される各axios.get
に対して個別のthen
呼び出しを行い、その後にのみ実行される最後のthen
を呼び出す方法はありますかallが解決され、オブジェクトにデータが入力されたのでデータを使用しますか?
さて、各then
でget
を使用せずに必要なことを行う方法を見つけました。 axios.get
に渡されたパラメーターには保存場所を決定するのに十分な情報が含まれているため、応答からパラメーターを読み取ることができるため、次のようなことができます。
let promises = [];
for (let i = 0; i < requests.length; i++) {
promises.Push(axios.get(request[i].url, { params: {...} }));
}
axios.all(promises)
.then(axios.spread((...args) => {
for (let i = 0; i < args.length; i++) {
myObject[args[i].config.params.saveLocation] = args[i].data;
}
}))
.then(/* use the data */);
これにより、使用前にすべてのデータが受信され、オブジェクトに保存されます。
2回目の試行の動作が実際にそのようなものである場合、それはaxios
がPromise/A +に準拠していないことを示しています。 then
コールバックの戻り値は、そのthen
によって返されるpromiseが満たされる値でなければなりません。これは配列にプッシュする約束なので、axios.all
がその約束に対して返す値は、最初にthen
コールバックを実行することによってのみ知ることができます。
イベントはthen
コールバックで明示的に値を返しませんが、これは上記のルールに影響しません。その場合、戻り値はundefined
であり、that対応するプロミスが解決されると、axios.all
によって提供される値。
特にルール2.2.7、2.2.7.1、2.3.2.1、2.3.2.2を参照してください Promise/A +の仕様で )。
したがって、代わりにPromise/A +準拠のpromise実装を使用することをお勧めします。 request-promise など、他にもいくつかのライブラリがあります。
または、ネイティブのES6 Promise実装を使用して、 http.request
メソッドを指定 を使用することもできます。
ES6はPromise.all
を提供し、約束が提供されたのと同じ順序で解決された値を提供することを保証します。
それぞれのthen
関数でアタッチされた配列にプロミスを渡すと、初期コードは意図したとおりに正常に機能します。
let promises = []; // array to hold all requests promises with their then
for (let i = 0; i < requests.length; i++) {
// adding every request to the array
promises.Push(
axios.get(request[i].url, { params: { ...} })
.then(response => { myObject[request[i].saveLocation] = response.data; })
);
}
// Resolving requests with their callbacks before procedding to the last then callback
axios.all(promises).then(/* use the data */);