首页 > 解决方案 > Microsoft Graph API Javascript SDK 承诺

问题描述

我刚刚摆脱了 Promise 链接,因为它非常令人困惑,并继续使用异步等待。我仍然无法获得所需的结果。如何从下面的代码中获取 finalResult() 的结果。它不断返回未决的承诺。我尝试执行以下操作

让 sampleData = 等待 finalResult()

在这里如何从 sampleData 获取数据?我还尝试将 then 调用附加到 finalResult 也不起作用。有什么帮助吗?我只需要下面代码中的 channelData

app.get("/graph/getChannelEvents", (req, res) => {
  var idToken = req.query.idToken;
  var teamId = req.query.teamId;
  var channelData = req.query.channelData;
  var tenantId = process.env.TENANT_ID;
  if (!idToken) {
    res.status(500).send("Could not find id token");
    return;
  }
  request(
    `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
      form: {
        grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
        client_id: process.env.APP_ID,
        client_secret: process.env.APP_Secret,
        scope: "Calendars.Read",
        requested_token_use: "on_behalf_of",
        assertion: idToken,
      },
    },
    async (error, response, body) => {
      const accessToken = JSON.parse(body)["access_token"];

      var client = MicrosoftGraph.Client.init({
        defaultVersion: "v1.0",
        debugLogging: true,
        authProvider: (done) => {
          done(null, accessToken);
        },
      });

      async function finalResult() {
        let cdata = await client
          .api(`/groups/${teamId}/events`)
          .header("Prefer", 'outlook.timezone="Pacific Standard Time"')
          .select("subject,onlinemeeting,start,end")
          .get();
        let channelData = await cdata.value.map(async (org) => {
          var channelId = url
            .parse(decodeURIComponent(org.onlineMeeting.joinUrl))
            .pathname.split("/")[3];
          var sessionData = await client
            .api(`/teams/${teamId}/channels`)
            .filter(`startswith(id, '${channelId}')`)
            .select("displayName")
            .get();
          let myData = await sessionData.value.map(async (u) => {
            return {
              sessionName: org.subject,
              channelName: u.displayName,
              channelId: channelId,
              startDate: org.start.dateTime.split("T")[0],
              endDate: org.end.dateTime.split("T")[0],
              startTime: org.start.dateTime.split("T")[1],
              endTime: org.end.dateTime.split("T")[1],
            };
          });
        });
        console.log(channelData);
      }

      finalResult();
    }
  );
});

标签: javascriptasync-await

解决方案


一个很好的解决方案是通过一个包装整个显示代码并使用函数返回该承诺的承诺使其异步。

之后,您将希望做出一系列承诺,以便能够一次全部调用它们并等待所有结果,然后再继续。您Promise.all()可以调用数组中的所有 promise 并使用它,就像使用带有.then(). 从 then() 接收到的值将是一个数组,其中包含来自 promiseArray 的 promise 的所有结果。

var getStuff = () => {
    //First and big promise starts here
    return new Promise( (resolve, reject) => {
        client.api(`/groups/${teamId}/events`)
            .header("Prefer", 'outlook.timezone="Pacific Standard Time"')
            .select("subject,onlinemeeting,start,end")
            .get()
            .then((result) => {
                // Create an array for your promises
                var promisesArray = [];
                result.value.map((org) => {
                    // Fill your array with every promise you need, each one containing just one call to your api
                    promisesArray.push(new Promise((arrayResolve, arrayReject) => {
                        console.log("top: " + org.subject);
                        var channelId = url
                        .parse(decodeURIComponent(org.onlineMeeting.joinUrl))
                        .pathname.split("/")[3];
                        client
                        .api(`/teams/${teamId}/channels`)
                        .filter(`startswith(id, '${channelId}')`)
                        .select("displayName")
                        .get()
                        .then((result) => {
                            const cdata = result.value.map((u) => {
                            console.log("down " + org.subject);
                            return {
                                sessionName: org.subject,
                                channelName: u.displayName,
                                channelId: channelId,
                                startDate: org.start.dateTime.split("T")[0],
                                endDate: org.end.dateTime.split("T")[0],
                                startTime: org.start.dateTime.split("T")[1],
                                endTime: org.end.dateTime.split("T")[1],
                            };
                            });
                        })
                        .then((result) => {
                            // Resolve individual promises
                            arrayResolve(result);
                        }).catch((err) => {
                            reject(err);
                        })
                    }));
                })
                // This executes all the promises at the same time
                Promise.all(promisesArray).then( (finalResult) => {
                    // Resolve big and initial promise
                    resolve(finalResult);
                }).catch((err) => {
                    reject(err);
                })
        })
    })
}

(注意:我只是将您现有的代码包装在一个函数中并完成了所需的大括号和括号。然后我添加了可以使这项工作按预期工作的承诺,但需要添加一些代码才能使其工作,因为我注意到您调用了一些未在您显示的代码中定义的变量)

在此之后,您可以调用此函数并使用“.then()”来接收您想要的值。

希望这可以帮助!


推荐阅读