2016-08-13 2 views
0

1. Как написать Promises синхронно в узле, чтобы я мог получить желаемый результат. Я новичок и буду признателен за любую помощь/предложение.Как написать синхронную функцию в узле, используя Promises

// This is my core function 

var compareData = function(userIdArray) { 
    return new Promise(function(resolve, reject) { 
    var missingArray = new Array(); 
    userIdArray.forEach(function(id) { 
     var options = { 
     method: 'POST', 
     url: 'http://localhost:6006/test1', 
     headers:{ 
     'content-type': 'application/json' }, 
      body: { email: id }, 
      json: true 
     }; 

     request(options, function (error, response, body) { 
     missingArray.push(body); 
     }); 
    }); 
    resolve(missingArray); 
    }); 
} 


//I'm calling my function here 

compareData(userIdArray) 
.then(function(missingArray){ 
    console.log("The Body is: "+ missingArray); 
}); 

/* I expect the console.log to print the missingArray with data from my POST call, 
but it prints an empty array. Can someone please tell me how to do this synchronously. 
I'm pretty new to Node and finding it difficult to understand.*/ 
+3

Обещания по определению async, вы можете * (делать) * возвращать обещание синхронно, но обещанное значение ** всегда ** разрешено async. – Thomas

+1

Обещание не может быть синхронным, а синхронный код вообще не нуждается в обещании, так что это мало смысла? – adeneo

+0

Вы решаете немедленно с помощью 'missingArray' var внутри вашего обещания. 'request' является асинхронным, поэтому ваш push будет вызван после того, как обещание будет разрешено, следовательно, пустой массив будет тогда функционировать. Что вам нужно, так это 'Promise.all', обернутый вокруг запросов для всех userIds. –

ответ

2

с bluebird и request-promise:

var Promise = require('bluebird'); 
var request = require('request-promise'); 

var compareData = function(userIdArray) { 
    //Promise.all(): 
     //takes an array of promises (and/or values), 
     //returns a promise of the resolved array 
    return Promise.all( 
     userIdArray.map(function(id){ 
      return request({ 
       method: 'POST', 
       url: 'http://localhost:6006/test1', 
       headers: { 'content-type': 'application/json' }, 
       body: { email: id }, 
       json: true 
      }); 
     }) 
    ); 
} 

есть все, что нуждается в дальнейшем объяснении?

0

Без библиотек, и предполагая request это уже не вернуть обещание

var compareData = function(userIdArray) { 
    return Promise.all(
     userIdArray.map(function(id) { 
      var options = { 
       method : 'POST', 
       url  : 'http://localhost:6006/test1', 
       headers : { 'content-type': 'application/json' }, 
       body : { email: id }, 
       json : true 
      }; 

      return new Promise(function(resolve, reject) { 
       request(options, function(error, response, body) { 
        if (error) { 
         reject(); 
        } else { 
         resolve(body); 
        } 
       }); 
      }); 
     }) 
    ); 
} 

compareData(userIdArray).then(function(missingArray) { 
    console.log(missingArray); 
}); 
2

Если вы не хотите использовать внешние библиотеки в соответствии с @Thomas ответ, вы можете использовать собственные обещания напрямую - и это не слишком много более многословным

var compareData = function compareData(userIdArray) { 
    return Promise.all(userIdArray.map(function (id) { 
     return new Promise(function (resolve, reject) { 
      var options = { 
       method: 'POST', 
       url: 'http://localhost:6006/test1', 
       headers: { 
        'content-type': 'application/json' 
       }, 
       body: { 
        email: id 
       }, 
       json: true 
      }; 
      return request(options, function (error, response, body) { 
       error ? reject(error) : resolve(body); 
      }); 
     }); 
    })); 
}; 

compareData(userIdArray) 
.then(function (missingArray) { 
    console.log("The Body is: " + missingArray); 
}); 

Или, как это узел, который может обрабатывать более современный код:

var compareData = userIdArray => 
    Promise.all(userIdArray.map(id => 
     new Promise((resolve, reject) => 
      request({ 
       method: 'POST', 
       url: 'http://localhost:6006/test1', 
       headers: { 
        'content-type': 'application/json' 
       }, 
       body: { 
        email: id 
       }, 
       json: true 
      }, (error, response, body) => error ? reject(error) : resolve(body)) 
     ) 
    )); 

compareData(userIdArray) 
.then(missingArray => 
    console.log("The Body is: "+ missingArray) 
); 
+0

Спасибо @Jaromanda X. Это отлично работает, но для возврата обещания требуется много времени. Я вызываю эту функцию compareData внутри моего запроса POST и время запроса до того, как это обещание разрешит и отправит ответ. Любое предложение? –

Смежные вопросы