最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Wrapping Node.js callbacks in Promises using Bluebird - Stack Overflow

programmeradmin0浏览0评论

How do I wrap a Node.js callback using a Promise in Bluebird? 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. 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. Here's the code without using promisifyAll. It calls sequelize to initialize the database and then makes an HTTP request to create the order. Bosth console.log statements are printed correctly:

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:

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.

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

What am I doing wrong?

How do I wrap a Node.js callback using a Promise in Bluebird? 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. 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. Here's the code without using promisifyAll. It calls sequelize to initialize the database and then makes an HTTP request to create the order. Bosth console.log statements are printed correctly:

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:

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.

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

What am I doing wrong?

Share Improve this question edited Mar 31, 2014 at 14:24 thefourtheye 240k53 gold badges465 silver badges500 bronze badges asked Mar 31, 2014 at 12:29 NareshNaresh 25.8k35 gold badges146 silver badges213 bronze badges 3
  • 1 possible duplicate of How do I convert an existing callback API to promises? – Bergi Commented Mar 31, 2014 at 13:04
  • See my edited answer (menting for notification) – Esailija Commented Mar 31, 2014 at 14:46
  • You have .then chained to a .then that returns nothing. Your original question is a duplicate and your edit is just about using .then handlers correctly. – Benjamin Gruenbaum Commented Mar 31, 2014 at 15:36
Add a ment  | 

1 Answer 1

Reset to default 8

You are not calling the promise returning version and not returning it either.

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(); 
发布评论

评论列表(0)

  1. 暂无评论