2016-08-13 75 views
0

1.如何在节点中同步写入Promises,以便获得所需的输出。我是一个新手,并会感谢任何帮助/建议。如何在使用Promise的节点中编写同步功能

// 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

承诺是按定义异步,你可以*(做)*同步返回承诺,但承诺的价值是**总是**解决异步。 – Thomas

+1

Promise不能同步,并且同步代码通常不需要承诺,所以没有多大意义? – adeneo

+0

您正在使用承诺中的'missingArray' var立即解决问题。 'request'是异步的,所以你的push将在promise被解析后被调用,因此在then函数中是空的数组。你需要的是一个包含所有用户标识请求的'Promise.all'。 –

回答

2

bluebirdrequest-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。这工作正常,但需要很长时间才能退还承诺。我在我的POST请求中调用了这个compareData函数,并且在这个承诺解析并发送响应之前,请求超时。任何建议? –