66316


javascript初心者です。(初めて3日目) promiseの結果を変数に格納したいのですが、昨日からずっと調べているのですが、やり方がわかりません。

【やりたいこと】  
フォルダに保存したプロジェクトのファイル一覧(配列)を、ブラウザ上に並べて表示させる。

【困っていること】  
async functionで取得した値(プロジェクト一覧の配列)に変数に格納したいが、出来ませんでした。  
console.logすると、array(2)と表示されて中身が見えるのですが、実際に中身を取り出そうとすると(例えばgli[0])  
undefindと表示されます。lengthを調べても0と出ています。  
中身が見えるのに取り出せないのは、不思議でした。global変数に格納しても同じ結果となりました。

【試したこと・調べたこと】  
・async functionを変数に格納するのではなく、asyncの内部で処理をしたほうが良いとのことだったので、  
処理をすべて内部に移動させたところ、処理はされたのですが、画像が表示されませんでした。→失敗  
(overlayなどとの相性でしょうか？？)

promiseの概念についての理解がまだ出来ていないのですが、.thenで処理結果へのアクセスは出来るにも関わらず、  
いろいろ調べても、その結果を格納できない理由が、理解できませんでした。。。

promiseの結果を変数に格納して、functionの外側から使用したいというのは、やはり使い方を間違っているのでしょうか。  
また正しい使い方をする場合、そのように書けばよいのでしょうか。

申し訳ないのですが、わかる方は教えてくだされば幸いです。

【コード】

[code]

    <script>
    async function get_list(){
    let li=await eel.projectlist()();//list型のobjectが返ってくる。(liに格納される)
        var txt =""
        for (let i = 0; i < li.length; i++){
                gli.push(li[i])
        }
        return li
    }
    window.onload = function() {
        gli=[];
        get_list().then(value => console.log(value));
        console.log(gli)
        for (let i = 0; i < gli.length; i++) {
            console.log(gli[i])
            var txt = txt+`<div class="col-lg-3 col-md-6 col-sm-6 work"> <a href="images/work-8.jpg" 　class="work-box"> <img src="images/work-8.jpg">
                    <div class="overlay">
                      <div class="overlay-caption">
                        <h5>Project Name</h5>
                        <p>${gli[i]}</p>
                      </div>
                    </div>
                    <!-- overlay --> 
                    </a> </div>`;}
       document.getElementById("message").innerHTML =txt;
    }
    </script>
    
[/code]


CC BY-SA 4.0
2020-05-05T06:56:34.900
66311
2020-05-05T11:41:00.693
2020-05-05T07:02:15.360
3475
39993
question
javascript promise
javascriptでpromiseの最終結果を変数へ格納する方法


JavaScriptの同期処理と非同期処理の理解が追いついていないかと思うので、実装の流れに混乱が生じていると考えられます。まずは（おそらく動くであろう）書き直したコードはこちらです。

[code]

    async function get_list() {
      // get_listの実行後のthenの第一引数で取得することができる
      return await eel.projectlist()();
    }
    
    window.onload = function () {
      get_list().then(function (gli) {
        var txt = "";
        for (let i = 0; i < gli.length; i++) {
          txt =
            txt +
            `<div class="col-lg-3 col-md-6 col-sm-6 work"> <a href="images/work-8.jpg" 　class="work-box"> <img src="images/work-8.jpg">
                        <div class="overlay">
                          <div class="overlay-caption">
                            <h5>Project Name</h5>
                            <p>${gli[i]}</p>
                          </div>
                        </div>
                        <!-- overlay --> 
                        </a> </div>`;
        }
        document.getElementById("message").innerHTML = txt;
      });
    };
    
[/code]

Promiseから値を取得するような場合、Promiseチェーンを繋げる必要があります。今回の質問では、`get_list`関数がPromiseを返すので、値を取得するためには、`then`を繋げ、callback中で値を操作する必要があります。

[code]

    get_list().then(function (value) {
      console.log(value); // Promise Chainで値を取得できる。
    })
    
[/code]

次に、Promiseは非同期で処理されるため、コードを書いた順番で処理されるとは限りません。

[code]

    get_list().then(function () {
      console.log("hello from promise chain!");
    })
    console.log("hello from out of promise chain!")
    
[/code]

これを実行すると、ログには以下の順番で出てくると思います。

[code]

    "hello from out of promise chain!"
    "hello from promise chain!"
    
[/code]

非同期処理はJavaScriptのruntimeによって制御されるため、実際に上記の順序出てくるかもしれないし、出てこないかもしれません。これは正確にはわかりません。ただ明らかなのは、Promise
ChainのCallback中に処理を書くことで非同期処理の完了を確実に取得することが可能です。

さて、ここまでの回答で不明な点があればもう少しPromiseについて学習してみてください。

**参考**

  * JavaScript Promiseの本: <https://azu.github.io/promises-book/>


CC BY-SA 4.0
2020-05-05T07:38:51.147
66316
2020-05-05T07:49:19.963
2020-05-05T07:49:19.963
7997
7997
66311
answer

[code]

    get_list().then(value => console.log(value));
    console.log(gli);
    
[/code]

`get_list()`がPromiseを返すasync関数なので、`then()`内で結果を使うか、`get_list()`の呼び出しを`await`する必要があります。

[code]

    window.onload = async function() {
      const gli = await get_list();
      ...
    
[/code]

また、`get_list()`は`eel.projectlist`の結果をコピーしているだけなので、必要なさそうです。

[code]

    window.onload = async function() {
      const gli = await eel.projectlist()();
      ...
    
[/code]


CC BY-SA 4.0
2020-05-05T11:41:00.693
66328
2020-05-05T11:41:00.693
3475
66311
answer