おじさんの毎日

おじさんですぅ

for文内にfetch書きたい時どうするか。

覚書です。



間違えたやつ



これが間違えたコードです。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    var articleDate, articlePath;

    for(var i = 0; i < r.length; i++) {
        articleDate = r[i].date;
        articlePath = r[i].path;
    
        fetch(articlePath)
        .then(response => response.text())
        .then(htmlString => {
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlString, "text/html");

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



これrって変数に入ってるJSONデータをfetch内で使いたかったんですけど、
fetch内でのarticleDateとarticlePathの中身が全部最後の要素になってしまってました。



これの原因がFetch文の仕様にあって、fetch文はいわゆる「非同期処理」というもので

非同期処理とは、あるタスクを実行をしている際に、他のタスクが別の処理を実行できる方式のことをいいます。 データベースから値を取得する際、通信状況によって取得まで時間がかかる処理とされています。 この時間のかかる処理を、シングルスレッドで実行すると、実行中は他のタスクを行うことができなくなります

Wantedly より



っていう感じになってます。
つまりFetchが実行している最中は何か処理することができないのです。
だからfor文のループがfetchを無視してしまい、fetch文を実行したときにはfor文のループが終わってしまっているっていうことです。



解決策



解決策です。
forループでletを使って変数を定義しましょう。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    for(var i = 0; i < r.length; i++) {
        let articleDate = r[i].date;
        let articlePath = r[i].path;
    
        fetch(articlePath)
        .then(response => response.text())
        .then(htmlString => {
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlString, "text/html");

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



これでOK。