2016-08-13 74 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函數,並且在這個承諾解析併發送響應之前,請求超時。任何建議? –