【问题标题】:Bluebird.js Promise not chaining .then()sBluebird.js Promise 不链接 .then()s
【发布时间】:2016-06-18 01:33:25
【问题描述】:
socket.on('new video', function(data) {
    console.log("New video")
    var addToCueP = Promise.promisify(addToCue)
    var getCueFromDbP = Promise.promisify(getCueFromDb)

    addToCueP(data.id, socket.nickname)
    .then(function() {
        return getCueFromDbP();
    })
    .then(function() {
        console.log("Emit change video")
        io.sockets.emit('change video', {id: data.id, title: data.title, nick: socket.nickname});
    })          
});

我正在使用 Bluebird 进行承诺,但我遇到了问题,addToCue 函数被调用,但之后的其他函数,例如 getCuefromDb 和 Socket 发射器没有被触发,有人知道我哪里出错了吗?

addToCue()

var addToCue = function(id, user) {
console.log("Add to cue")
var video = new Video();
video.id = id;
video.user = user;
video.save(function(err, data) {
    if (err) {
        console.log(err)
    } else {
        return true
    }
});
}

getCueFromDb()

var getCueFromDb = function(callback) {
Video.find({}).exec(function(err, videos) {
        if (err) {
            return err;
        }
        if (videos.length) {
            cue = []; // empty array
            videos.forEach(function(video) {
                cue.push(video.id) // push all the videos from db into cue array
            });
            io.sockets.emit('send cue', {cue: cue});
            console.log("getCueFromDb", cue)
            if (callback) {
                callback();
                return
            }
            else {
                return
            }
        }
        else {
            cue = [];
            io.sockets.emit('send cue', {cue: cue});
            console.log("getCueFromDb (no videos)", cue)
            if (callback)
                callback()
            else
                return
        }
})
}

【问题讨论】:

  • addToCue()getCueFromDb() 的签名是什么?如果你已经在使用 Promises,为什么还要承诺这些功能呢?他们为什么不返回 Promise?
  • 它们只是普通函数,但我希望它们按此顺序执行我认为这是正确的方法而不是回调我错了吗?
  • 您没有处理错误,根据您的描述,一种可能的情况是 addToCueP 抛出或拒绝错误
  • 我同意 Promise 优于回调。但是this is the code 承诺一些事情。只返回一个 Promise 不是比让这个引擎猜测如何承诺你的函数更简单吗?但除此之外,您没有回答有关addToCue()getCueFromDb() 的实际签名的问题。
  • 用 addToCue() 和 getCueFromDb() 函数更新了问题,开始认为 promisify 不是我正在寻找的尝试加入 Bluebird 方法的方法,但它仍然没有在正确的顺序嗯...

标签: javascript socket.io promise bluebird


【解决方案1】:

addToCue() 不接受正确类型的参数来调用 .promisify() - 因此 promisify 不能正常使用它。

addToCue() 的最后一个参数必须是异步操作完成时调用的回调,并且该回调的第一个参数必须是错误值,第二个参数可以是结果。

现在,由于您将代码控制为 addToCue(),因此您只需更改其代码以返回基于底层异步操作解析/拒绝的承诺,而根本不使用 .promisify()

var addToCue = function(id, user) {
    return new Promise(function(resolve, reject) {
        console.log("Add to cue")
        var video = new Video();
        video.id = id;
        video.user = user;
        video.save(function(err, data) {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
}

或者,您可以在 video.save() 上使用 .promisify() 或在 Video 对象上使用 .promisifyAll()

或者,如果您的 Video 接口已经支持 Promise,您可以使用它的原生支持并返回该 Promise。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 2018-11-14
    • 2014-11-05
    相关资源
    最近更新 更多