使用Array.map时使用Promise.all但仍无效的嵌套承诺

时间:2017-04-03 10:25:31

标签: javascript arrays node.js mongoose promise

我现在已经把头撞在墙上一段时间了。我有一些节点代码可以拉出一堆googlecalendar事件,然后将它们映射到不同的对象结构上,以便在我的webapp中使用...作为其中的一部分,我需要将google日历事件中的用户与我的webapp中的用户进行匹配#39;数据库。这是代码:

router.post('/getCalendar', function(req,res) {  
  // authentication
  var oauth2Client = getOAuthClient();
  var session = req.session;
  oauth2Client.setCredentials({
    access_token: req.user.google.token,
    refresh_token: req.user.google.refreshToken,
    expiry_date: true
  })

  var p = new Promise(function (resolve, reject) {
    // get the next 20 calendar events   
    var calendar = google.calendar('v3');
      calendar.events.list({
        auth: oauth2Client,
        calendarId: 'primary',
        timeMin: (new Date()).toISOString(),
        maxResults: 20,
        singleEvents: true,
        orderBy: 'startTime'
      }, function(err, response) {
        if (err) console.log('err',err)
          // displays all the events
        if (response) console.log('response',response)
        if(response) {
          var events = response.items;
          resolve(events || err);  
        }        
    });

  }).then(function (data) {

    var newdata = data.map(function(item) {
      // create the new object structure and populate with some details
      newObj = {
          _id: item.id,
          _title: item.summary,
          group: [req.headers.group],
          fields: [],
          assignedTo: [],
          google: "calendar",
          googledata: item,
          _category: []
      }

      var extendedFields = {}

      // get the list of attendees
      attendees = item.attendees.map(function(user) {
        var attendee = user.email;
        return attendee;
      })

      // pulls the user information for each attendee using promises
      var promises = attendees.map(function(email) {
        return new Promise(function(resolve, reject) {

          // data is in a mongodb, using mongoose
          User.findOne({'google.email': email}).exec(function (err, user) {
            if (err) return resolve(null);
            resolve(user); //not using reject at all so the Promise.all shouldn't fail
          });
        })
      })

      Promise.all(promises)
        .then(function(value) {
          value.forEach(function(user) {
            if(promise !== null) {
              newObj.assignedTo.push(user);  
            }
          });

          return newObj

      }).catch((error) => {console.log(error)})

  })

  res.json(newdata)
  })

});

我正在使用Promise.all等到所有的promise都已解决,但它似乎在完成第一个之前移动到data数组中的下一个项目。欢迎任何指导。如果需要更多详细信息,请告诉我。

谢谢。

1 个答案:

答案 0 :(得分:0)

  1. 返回Promise.all的承诺。

    return Promise.all(promises)
        .then(function(value) {
          value.forEach(function(user) {
            // user !== null ? 
            if(promise !== null) {
              newObj.assignedTo.push(user);  
            }
          });
    
          return newObj
        })
        .catch((error) => {console.log(error)})
    
  2. 在newdata上使用Promise.all。

    Promise.all(newdata)
      .then(function (newObjs) {
        // newObjs is the Array of newObj in your code
        res.json(newObjs);
      })
      .catch(function (err) {
        console.log(err);
      });