Node.js 如何在承诺中使用循环

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(函数

我试图在承诺内执行for循环,但没有成功,我认为我的问题与在哪里调用resolve有关,但我不确定

/*
*获取用户的对话
*@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
}));