javascript - 将 socket.on 包装为 promise

标签 javascript angularjs socket.io promise angularjs-service

我正在创建一个服务,其函数init作为resolve。首先,它使用连接 ID 创建一个文件夹,然后在其中写入一些默认文件。应该记录文件夹(即连接的id),这就是this.dir的用途。

以下代码很好地调用了initDir。但是,它不会调用initFiles(即,不会调用alert("here"))。我猜这是因为 initDir 没有兑现 promise 。

有谁知道如何修改吗?

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.then更改为this.initDir().then后,我有以下代码。它很好地显示了init内部initDir内部initFiles之前。但是,它不会显示内部 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)
    })
};

最佳答案

它不起作用,因为 socket.on 不返回其回调的返回值。

尝试用 Promise 包装代码并在回调中解析,而不是仅仅返回。

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

确保您正在返回新的 Promise,并且正在解析您希望等待的最终值。

关于javascript - 将 socket.on 包装为 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42489997/

相关文章:

javascript - 无法播放通过 JS 创建的嵌入在 iframe 中的 youtube 视频

javascript - 如何获取所有不同的下拉列表是否已选择值

javascript - 用于跨浏览器 SELECT Dropdown 的 AngularJs 指令

http - 配置 Nginx 和 Socket.IO

javascript - 显示来自数据库 AngularJS 的值

javascript - 使用 angularjs ng-class 更改每张卡片的颜色

javascript - AngularJS 仅创建一次 Controller

django - 实现 Django 和 socket.io 协同工作

javascript - socket.io - 多个事件性能

javascript - 在 Javascript 中触发 "paste"事件