Node.js 如何在承诺中使用循环
我试图在承诺内执行for循环,但没有成功,我认为我的问题与在哪里调用resolve有关,但我不确定Node.js 如何在承诺中使用循环,node.js,reactjs,promise,Node.js,Reactjs,Promise,我试图在承诺内执行for循环,但没有成功,我认为我的问题与在哪里调用resolve有关,但我不确定 /* *获取用户的对话 *@param user{String} */ 函数getConversations(用户){ 返回新承诺(功能(解决、拒绝){ var conversations=user.conversations var newConversations=[] for(会话的var对话){ helpergetconva(conversation.ConversID).then(函数
/*
*获取用户的对话
*@param user{String}
*/
函数getConversations(用户){
返回新承诺(功能(解决、拒绝){
var conversations=user.conversations
var newConversations=[]
for(会话的var对话){
helpergetconva(conversation.ConversID).then(函数(conva){
newConversations.push(createConversationObject({消息:[],名称:corba.conversationName,用户:[“broulaye”,“doumbia”],Id:corba.conversationID}))
}).catch(函数(原因){
日志(“查找对话2时失败:”+原因)
})
}
解析(新对话)
})
}
函数helpergetconva(convalid){
返回新承诺(功能(解决、拒绝){
query.findConversation(convalid).then(函数(convers){
if(逆){
log(“找到对话:+convers”)
}
否则{
log(“找不到对话:+convers”)
}
解析(逆)
}).catch(函数(原因){
console.log(“查找对话时失败:”+原因)
})
})
}
一种方法是使用map而不是for in在数组中收集承诺。然后使用Promise.all()等待所有问题得到解决(或一个问题被拒绝)
比如:
return Promise.all(conversations.map(conversation => {
return helperGetConvo(...).then().catch();
}
记住,所有的承诺都必须要么解决,要么拒绝。如果不遵守此规则,您会遇到麻烦。一种方法是使用map而不是for in在数组中收集承诺。然后使用Promise.all()等待所有问题得到解决(或一个问题被拒绝) 比如:
return Promise.all(conversations.map(conversation => {
return helperGetConvo(...).then().catch();
}
记住,所有的承诺都必须要么解决,要么拒绝。如果你不遵守这条规则,你就会陷入麻烦。你需要使用
承诺。所有
function getConversations(user){
var conversations = user.Conversations
var promises = conversations.map(c=>helperGetConvo(c.ConversID))
return Promise.all(promises)
.then(data=>{
let newConversations = data.map(convo=>{
return createConversationObject({messages:[], name:convo.conversationName, users:["broulaye", "doumbia"], Id:convo.conversationID})
})
return newConversations
})
.catch(reason=>{
console.log("failure when finding conversation: " + reason)
})
}
像这样使用函数
getConversations(user).then(newConversations=>{
//your code
})
您需要使用Promise.all
function getConversations(user){
var conversations = user.Conversations
var promises = conversations.map(c=>helperGetConvo(c.ConversID))
return Promise.all(promises)
.then(data=>{
let newConversations = data.map(convo=>{
return createConversationObject({messages:[], name:convo.conversationName, users:["broulaye", "doumbia"], Id:convo.conversationID})
})
return newConversations
})
.catch(reason=>{
console.log("failure when finding conversation: " + reason)
})
}
像这样使用函数
getConversations(user).then(newConversations=>{
//your code
})
问题是,当您调用resolve
时,您正在解析整个承诺。for循环不会等待每个helpergetconva()
调用完成,然后再继续下一个调用。无论这些承诺中的哪一个符合,那么
语句首先将调用resolve
,这就是您的外部承诺将要解决的问题
有关承诺的更多信息,请访问:
如果要等待一组承诺完成,请使用。它接受一个承诺列表,并且只有在所有承诺都成功完成时才会解决
function getConversations(user) {
return new Promise(function (resolve, reject) {
var conversations = user.Conversations;
var newConversations = [];
//create a list of promises
var promises = [];
for (var conversation of conversations) {
// push each promise into our array
promises.push(
helperGetConvo(conversation.ConversID).then(function (convo) {
newConversations.push(createConversationObject({
messages: [],
name: convo.conversationName,
users: ['broulaye', 'doumbia'],
Id: convo.conversationID
}));
}).catch(function (reason) {
console.log('failure when finding conversation 2: ' + reason);
})
);
}
// wait for all promises to complete
// when then do, resolve the newConversations variable
// which will now have all of the conversation objects that we wanted to create
Promise.all(promises).then(() => resolve(newConversations)).catch(reject);
});
}
您还可以使用async/await来清理这个问题。Async/await提供了一些很好的语法糖,可以消除执行返回新承诺(…)
的需要。下一个代码段不是使用async/await的最佳方式,因为for循环将同步处理所有内容(一次一个会话)。这篇博文对我理解在迭代问题中使用async/await有很大帮助:
异步函数返回承诺。因此,您可以通过执行getConversations(user)调用此函数。然后(…)
。但我认为async/await使您的代码看起来更干净。当然,您可以做进一步的优化,但希望这能让您开始。问题是,当您调用resolve
时,您正在解决整个承诺。for循环不会等待每个helpergetconva()
调用完成,然后再继续下一个调用。无论这些承诺中的哪一个符合,那么
语句首先将调用resolve
,这就是您的外部承诺将要解决的问题
有关承诺的更多信息,请访问:
如果要等待一组承诺完成,请使用。它接受一个承诺列表,并且只有在所有承诺都成功完成时才会解决
function getConversations(user) {
return new Promise(function (resolve, reject) {
var conversations = user.Conversations;
var newConversations = [];
//create a list of promises
var promises = [];
for (var conversation of conversations) {
// push each promise into our array
promises.push(
helperGetConvo(conversation.ConversID).then(function (convo) {
newConversations.push(createConversationObject({
messages: [],
name: convo.conversationName,
users: ['broulaye', 'doumbia'],
Id: convo.conversationID
}));
}).catch(function (reason) {
console.log('failure when finding conversation 2: ' + reason);
})
);
}
// wait for all promises to complete
// when then do, resolve the newConversations variable
// which will now have all of the conversation objects that we wanted to create
Promise.all(promises).then(() => resolve(newConversations)).catch(reject);
});
}
您还可以使用async/await来清理这个问题。Async/await提供了一些很好的语法糖,可以消除执行返回新承诺(…)
的需要。下一个代码段不是使用async/await的最佳方式,因为for循环将同步处理所有内容(一次一个会话)。这篇博文对我理解在迭代问题中使用async/await有很大帮助:
异步函数返回承诺。因此,您可以通过执行getConversations(user)调用此函数。然后(…)
。但我认为async/await使您的代码看起来更干净。当然,您还可以做进一步的优化,但希望这能让您开始。您可以在我试图解决类似问题时发现的帮助函数中循环一个承诺。我使用此方法循环承诺,因为它不会在第一次拒绝承诺时崩溃。相反,我可以处理resolve或reject,并在循环完成后返回最终结果。下面代码片段中的承诺是使用bluebird
我用一些虚拟数据修改了您的代码示例,并使其与helper函数一起工作。因此,我相信您的getConversations函数如下所示:
function getConversations(user) {
var conversations = user.Conversations;
var newConversations = [];
var stop = conversations.length;
var index = 0
//loop promise
return promiseWhile(() => {
// Condition for stopping
return index < stop;
}, () => {
// Action to run, should return a promise
return new Promise((resolve, reject) => {
helperGetConvo(conversations[index].ConversID)
.then(function(convo) {
newConversations.push(createConversationObject({
messages: [],
name: convo.conversationName,
users: ['broulaye', 'doumbia'],
Id: convo.conversationID
}));
index++;
resolve();
})
.catch((error) => {
console.log('failure when finding conversation: ' + error);
index++;
resolve();
});
})
})
//This will execute when loop ends
.then(() => {
return newConversations;
});
}
函数getConversations(用户){
var conversations=user.conversations;
var newConversations=[];
var stop=conversations.length;
var指数=0
//循环承诺
归还承诺书(()=>{
//停车条件
返回指数<停止;
}, () => {
//要运行的操作,应返回一个承诺
返回新承诺((解决、拒绝)=>{
HelperGetConva(对话[index].Conversion)
.然后(功能(车队){
newConversations.push(createConversationObject({
信息:[],
名称:conva.conversationName,
用户:['broulaye','doumbia'],
Id:conva.conversationID
}));