Как обещать эту функцию - nodejs

У меня есть вызов ajax, который должен вернуть обещание. Функция выглядит следующим образом

client.tickets.create(ticket,  function(err, req, result) {
  if (err) {    
    logger.error(err);

    return false;
  }

  return JSON.stringify(result);
});

Мне нужно дождаться выполнения этой функции, прежде чем я смогу выполнить следующее действие. Как я могу обещать эту функцию?

Я попробовал следующее, и это дало мне сообщение об ошибке Cannot call method then of undefined:

return client.tickets.create(ticket).then(function(result){
    return JSON.stringify(result);
},function(err){
    logger.error(err);
    return false;
});

person chaithu    schedule 12.01.2016    source источник
comment
ты используешь какие-либо обещания API?   -  person Raja Sekar    schedule 12.01.2016


Ответы (3)


У вас есть ошибка, потому что create() не является обещанием. Обещать асинхронную функцию довольно просто (в настоящее время в nodejs есть встроенная поддержка Promise):

function createTicket(ticket) {
    // 1 - Create a new Promise
    return new Promise(function (resolve, reject) {
        // 2 - Copy-paste your code inside this function
        client.tickets.create(ticket, function (err, req, result) {
            // 3 - in your async function's callback
            // replace return by reject (for the errors) and resolve (for the results)
            if (err) {
                reject(err);
            } else {
                resolve(JSON.stringify(result));
            }
        });
    });
}

// 4 - consume your promise with then() (resolved promise) and catch (rejected promise)
createTicket(ticket).then(function (result) {
    // deal with result here
}).catch(function (err) {
    // deal with error here
});
person Shanoor    schedule 12.01.2016
comment
В релизе-кандидате для Node.js 8.0.0 есть новая утилита util.promisify, которая инкапсулирует возможность обещания любой функции. Он не намного отличается от подходов, предложенных в другом ответе, но имеет то преимущество, что является основным методом. Вы можете прочитать больше в этом посте - person Bruno; 16.05.2017

вместо того, чтобы вручную оборачивать асинхронный код в обещания, я бы посоветовал использовать такие библиотеки, как Bluebird, чтобы сделать это за вас:

var Bluebird = require('bluebird');

//either 
client.tickets = Bluebird.promisifyAll(client.tickets);
//or 
client.tickets.createAsync = Bluebird.promisify(client.tickets.create);
...
    return client.tickets.createAsync(ticket)
      .then(JSON.stringify)
      .catch(err => {
        logger.error(error); 
        return false
      });
person mido    schedule 12.01.2016

function createTicket(){
var deferred = Q.defer()
client.tickets.create(ticket,  function(err, req, result) {
     if (err) { 
                logger.error(err);
                return deferred.reject(err)
            }
   return deferred.resolve(result)
});
}

createTicket().then(function(){
    //success here
}, function(){
    //failure here
});

Используя Q api, вы можете выполнить обещание.

person Raja Sekar    schedule 12.01.2016