2016-07-20 3 views
0

私は流星反応プロジェクトに取り組んでおり、非同期のローカルストレージからデータをロードしたいと考えています。残念ながら、バインドを使用してもコールバックからデータを取得できませんでした。私は複数の方法を試しましたが、どちらも動作させることができませんでしたが、確かに何かが欠けています。コールバック内からオブジェクトを作成/調整する

私は可能な限り離れていましたが、文脈のためにいくつかを残していました。

私の理解から、これらの単純な整数を設定するトラックオブジェクトにのみ関連付けることができます。ブーリアンは正常に動作します。

render() { 
    const { audioCollection } = this.props; // database collection, async hence the following if check 
    if (audioCollection) { 
     this.tracks = audioCollection.audio(); // setting tracks for later use 
     // make sure tracks are loaded and only run once, as we do this in the react renderer 
     if (this.tracks && !this.state.tracksLoaded) { 
      var trackLoadedCount = 0; 
      this.tracks.forEach((track, i) => { // I tried to use forEach and map here 
       // now we try to load the data from local storage and if it fails fall back to the remote server 
       LocalForage.getItem(track.file_id).then(function(err, file) { 
        if (!err && file) { 
         console.log(track.file_id + ' from cache') 
         var blob = new Blob([file]); 
         fileURI = window.URL.createObjectURL(blob); 
        } else { 
         console.log(track.file_id + ' from database') 
         fileURI = audioCollection.audioLink(track.file_id); 
        } 
        track.fileURI = fileURI; // assigning the retrieved data uri to the track object, also tried to set it on the original parent object not the extracted one from the forEach/map 
        console.log(fileURI + ' ' + track.fileURI) // yes, both are set 
        trackLoadedCount++; // increasing the tracks loaded count, to calculate if all have been loaded and to test if it can write outside of the callback, which it does 
        // if all files have been processed, set state loaded, this works too. 
        if (trackLoadedCount == this.tracks.length) { 
         this.setState({ 
          tracksLoaded: true, 
         }) 
        } 
       }.bind(track, this)) 
      }); 
     } 
    } 
    // once all has been processed we try to retrieve the fileURI, but it isn't set :(
    if (audioCollection && this.tracks && this.state.tracksLoaded) { 
     console.log('all loaded ' + this.tracks.length) 
     this.tracks.map(track => { 
      console.log('track: ' + track.file_id + ' ' + track.fileURI) // file_id is set, fileURI is not 
     }) 
    } 

    // we only log 
    return (
     <Content {...this.props}> 
      <div>just console output</div> 
     </Content> 
    ); 
} 

私はより多くのアプローチを試してみました:tracksLoadedような状態にする配列(仕事を動作しませんでした)

  • は非同期呼び出し前に、新しいVARを定義し、その値を設定するなどのトラックを書く

    • コールバック内からtrackLoadedCount(バインドありとバインドなし)のように(動作しません)

    tracksLoadedで動作しているのはなぜですか? d trackLoadedCount? Firiceグエン

    render() { 
        const { audioCollection } = this.props; 
        if (audioCollection) { 
         this.tracks = audioCollection.audio(); 
         if (this.tracks && !this.state.tracksLoaded) { 
          var trackLoadedCount = 0; 
          this.tracks.forEach((track, i, trackArray) => { 
           LocalForage.getItem(track.file_id).then(function(err, file) { 
            if (!err && file) { 
             console.log(track.file_id + ' from cache') 
             var blob = new Blob([file]); 
             fileURI = window.URL.createObjectURL(blob); 
            } else { 
             console.log(track.file_id + ' from database') 
             fileURI = audioCollection.audioLink(track.file_id); 
            } 
            track.fileURI = fileURI; 
            console.log('1. ' + track.file_id + ' ' + track.fileURI); 
            trackArray[i] = track; 
            console.log('2. ' + track.file_id + ' ' + trackArray[i].fileURI); 
            trackLoadedCount++; 
            if (trackLoadedCount == this.tracks.length) { 
             this.setState({ 
              tracksLoaded: true, 
             }) 
            } 
           }.bind(track, this)) 
          }); 
         } 
        } 
        if (audioCollection && this.tracks && this.state.tracksLoaded) { 
         console.log('all loaded ' + this.tracks.length) 
         this.tracks.map(track => { 
          console.log('3. ' + track.file_id + ' ' + track.fileURI) // file_id is set, fileURI is not 
         }) 
        } 
    
        return (
         <Content {...this.props}> 
          <div>just console output</div> 
         </Content> 
        ); 
    } 
    

    戻り

    回答
    MXqniBNnq4zCfZz5Q from database 
    1. http://localhost:3000/cdn/storage/files/MXqniBNnq4zCfZz5Q/original/MXqniBNnq4zCfZz5Q.m4a 
    2. http://localhost:3000/cdn/storage/files/MXqniBNnq4zCfZz5Q/original/MXqniBNnq4zCfZz5Q.m4a 
    keBWP6xb9PyEJhEzo from database 
    1. http://localhost:3000/cdn/storage/files/keBWP6xb9PyEJhEzo/original/keBWP6xb9PyEJhEzo.m4a 
    2. http://localhost:3000/cdn/storage/files/keBWP6xb9PyEJhEzo/original/keBWP6xb9PyEJhEzo.m4a 
    K2J2W9W26DDBNoCcg from database 
    1. http://localhost:3000/cdn/storage/files/K2J2W9W26DDBNoCcg/original/K2J2W9W26DDBNoCcg.m4a 
    2. http://localhost:3000/cdn/storage/files/K2J2W9W26DDBNoCcg/original/K2J2W9W26DDBNoCcg.m4a 
    all loaded 3 
    3. MXqniBNnq4zCfZz5Q undefined 
    3. keBWP6xb9PyEJhEzo undefined 
    3. K2J2W9W26DDBNoCcg undefined 
    

    に関する

    アップデートので、問題が解消されません。

  • 答えて

    0

    forEachは、要素のコピーを提供します。 trackは単なるコピーであり、元のコピーではありません。配列内の要素を指していません。あなたはこれを試すことができます。

    this.tracks.forEach(track, i, trackArray) => { 
        // change `track` value 
        ... 
        trackArray[i] = track; 
    }); 
    

    それともmap方法

    +0

    のforEachはそれはそれは何もおかしく意味を成さないだろうo.0でないこと方法がないを試してみてください!私はそれが間違っていると言っているわけではないが、私はショックを受けている。あなたはこの主張のためのドキュメンテーションのリファレンスを持っていますか? – Dellirium

    +0

    私は今年6月までC++で働いていました。私が説明している方法がCポインタの可能性が高いかもしれません。私の知る限り、Javascriptには「参照渡し」のようなものはありません。呼び出しコンテキストによって異なります。 'forEach'の場合は、' forEach'を起動するコールバックに依存し、配列自体はそうではありません。これまでのところ、それらは私がJavascriptについて今まで理解しているものです。私が提案する解決策は、私の経験からです。私が間違っていれば私を修正してください。 –

    +0

    残念ながら私はどちらもうまくいきませんでしたし、私は親オブジェクト 'this.tracks [i] .fileURI = fileURI;にも割り当てようとしましたが、どちらもうまくいきませんでした:( – user2693017

    関連する問題