2017-02-27 12 views
1

initとしてresolveというサービスを提供しています。まず、接続のIDを持つフォルダを作成し、そこにいくつかのデフォルトファイルを書き出します。 this.dirの目的であるフォルダ(つまり、接続のID)を記録する必要があります。約束としてのソケット

次のコードは、よくinitDirを呼び出します。ただし、initFilesは呼び出されません(つまり、alert("here")は呼び出されません)。私はそれがinitDirが約束としてうまく作られなかったからだと思います。

誰もそれを修正する方法を知っていますか?サーバー側では

this.files = [ ... ... ]; 

this.dir = "public/tmp/default/"; 

this.initDir = function() { 
    var socket = io.connect(); 
    return socket.on('id', function (id) { 
     var dir = "public/tmp/" + id + "/"; 
     return $http.post('mkdir', { dir: dir }) 
      .then(function() { 
       this.dir = dir; 
      }) 
    }) 
} 

this.initFiles = function (dir, files) { 
    return $http.post('writeFile', { dir: dir, file: files[0] }) 
     .then(function (res) { 
      $http.post('writeFile', { dir: dir, file: files[1] }) 
       .then(function (res) { 
        console.log("saved 2 files") 
       }) 
      }) 
    }) 
} 

this.init = function() { 
    return this.initDir() 
     .then(function (res) { 
      alert("here"); 
      this.initFiles(this.dir, this.files) 
     }) 
} 

、それだけですべての接続の後に接続IDを送信します。

io.sockets.on('connection', function (socket) { 
    socket.emit('id', socket.id); 
} 

を編集1: @epiquerasの答えに続いて、私は、コードを変更しました。次のコードは、しかし、それはinside initDirを呼び出すことはありません、inside initを呼び出します....

var dirP = "public/tmp/default/"; 

this.initDir = function() { 
    return new Promise(function (resolve, reject) { 
     alert("inside initDir") 
     var socket = io.connect(); 
     socket.on('id', function (id) { 
      var dir = "public/tmp/" + id + "/"; 
      $http.post('mkdir', { dir: dir }) 
       .then(function() { 
        dirP = dir; 
        resolve(dirP) 
       }) 
     }) 
    })  
} 

this.init = function (files) { 
    alert("inside init"); 
    return initDir 
     .then(function (dir) { 
      alert("before initFiles"); 
      this.initFiles(dir, files) 
     }) 
} 

編集2:this.initDir().theninitDir.thenを変更した後、私は次のコードを持っています。それはよくinside init,inside initDir,before initFilesを示します。ただし、inside initFilesを表示したり、ファイルを書き込んだりしません。

this.initDir = function() { 
    return new Promise(function (resolve, reject) { 
     console.log("inside initDir") 
     var socket = io.connect(); 
     socket.on('id', function (id) { 
      var dir = "public/tmp/" + id + "/"; 
      $http.post('mkdir', { dir: dir }) 
       .then(function() { 
        dirP = dir; 
        resolve(dirP) 
       }) 
     }) 
    })  
}; 

this.initFiles = function (dir, files) { 
    console.log("initFiles: " + dir); 
    return $http.post('writeFile', { dir: dir, file: files[0] }) 
     .then(function (res) { 
      $http.post('writeFile', { dir: dir, file: files[1] }) 
       .then(function (res) { 
        console.log("saved 2 files") 
       }) 
      }) 
    }) 
} 

this.init = function (files) { 
    console.log("inside init"); 
    return this.initDir().then(function (dir) { 
     console.log("before initFiles " + dir + JSON.stringify(files)); 
     this.initFiles(dir, files) 
    }) 
}; 

答えて

0

socket.onがコールバックの戻り値を返さないため、機能しません。

コードを約束してラッピングし、返す代わりにコールバック内で解決してください。

initDir() { 
    return new Promise(function(resolve, reject) { 
     socket.on..... 
      $http.post.....then(resolve) 
    } 
} 

新しいプロミスを返すことを確認し、あなたが待つ最終的な価値を解決していることを確認してください。

+0

'initDir'の中に' this.dir'に値を代入すれば、それはサービスに記録されますか?約束と価値(すなわち、「dir」)を返すことは可能であり、良い習慣ですか? – SoftTimur

+0

".then"コールバック内の "this"は、外部 "this.dir"と同じオブジェクトを参照しません。 「this」は、関数が代わって呼び出されるオブジェクトを指します。この場合、おそらく約束の実装のハンドラオブジェクトによって呼び出されます。グローバル変数または静的変数を使用する方が良いでしょう。 – epiqueras

+0

ランタイムツールまたはビルドツールがES6をサポートしている場合は、矢印機能を使用します。矢印関数は、定義されている場所の "this"を保持します。 – epiqueras