2017-02-27 77 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