2017-02-27 79 views
1

我正在提供服務,功能initresolve。首先,它會創建一個具有連接標識的文件夾,然後在其中寫入一些默認文件。應記錄文件夾(即連接的ID),這是this.dir的目的。作爲承諾包裝socket.on

以下代碼調用的很好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 init,但它不叫inside initDir ....

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:改變initDir.thenthis.initDir().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) 
    } 
} 

確保您返回新的Promise,並且您正在解決您希望等待的最終值。

+0

您是否認爲如果我們爲'initDir'內的'this.dir'賦值,它將被記錄在服務中?返回一個承諾和一個價值(例如'dir')是否有可能並且是一個好習慣? – SoftTimur

+0

「.then」回調中的「this」不會引用與外部「this.dir」相同的對象。 「this」是指代表該函數被調用的對象。在這種情況下,它可能會被您的承諾實現的處理程序對象調用。只使用全局變量或靜態變量會更好。 – epiqueras

+0

或者如果您的運行時或構建工具支持ES6,則使用箭頭函數。箭頭功能保留了他們所定義位置的「this」。 – epiqueras