简体   繁体   English

使用Bluebird包装Promise中的Node.js回调

[英]Wrapping Node.js callbacks in Promises using Bluebird

How do I wrap a Node.js callback using a Promise in Bluebird? 如何使用Bluebird中的Promise包装Node.js回调? This is what I came up with, but wanted to know if there is a better way: 这就是我想出来的,但想知道是否有更好的方法:

return new Promise(function(onFulfilled, onRejected) {
    nodeCall(function(err, res) {
            if (err) {
                onRejected(err);
            }
            onFulfilled(res);
        });
});

Is there a cleaner way to do this if only an error needs to be returned back? 如果只需要返回错误,是否有更简洁的方法来执行此操作?

Edit I tried to use Promise.promisifyAll(), but the result is not being propagated to the then clause. 编辑我试图使用Promise.promisifyAll(),但结果没有传播到then子句。 My specific example is shown below. 我的具体示例如下所示。 I am using two libraries: a) sequelize, which returns promises, b) supertest (used for testing http requests), which uses node style callbacks. 我正在使用两个库:a)sequelize,它返回promises,b)supertest(用于测试http请求),它使用节点样式的回调。 Here's the code without using promisifyAll. 这是不使用promisifyAll的代码。 It calls sequelize to initialize the database and then makes an HTTP request to create the order. 它调用sequelize初始化数据库,然后发出HTTP请求来创建订单。 Bosth console.log statements are printed correctly: 正确打印Bosth console.log语句:

var request = require('supertest');

describe('Test', function() {
    before(function(done) {
        // Sync the database
        sequelize.sync(
        ).then(function() {
            console.log('Create an order');
            request(app)
                .post('/orders')
                .send({
                    customer: 'John Smith'
                })
                .end(function(err, res) {
                    console.log('order:', res.body);
                    done();
                });
        });
    });

    ...
});

Now I try to use promisifyAll, so that I can chain the calls with then: 现在我尝试使用promisifyAll,以便我可以使用then链接调用:

var request = require('supertest');
Promise.promisifyAll(request.prototype);

describe('Test', function() {
    before(function(done) {
        // Sync the database
        sequelize.sync(
        ).then(function() {
            console.log('Create an order');
            request(app)
                .post('/orders')
                .send({
                    customer: 'John Smith'
                })
                .end();
        }).then(function(res) {
            console.log('order:', res.body);
            done();
        });
    });

    ...
});

When I get to the second console.log the res argument is undefined. 当我到达第二个console.log时,res参数是未定义的。

Create an order
Possibly unhandled TypeError: Cannot read property 'body' of undefined

What am I doing wrong? 我究竟做错了什么?

You are not calling the promise returning version and not returning it either. 你没有调用promise返回版本,也没有返回它。

Try this: 尝试这个:

   // Add a return statement so the promise is chained
   return request(app)
            .post('/orders')
            .send({
                customer: 'John Smith'
            })
            // Call the promise returning version of .end()
            .endAsync(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM