为什么以下JavaScript Promise会返回所有电子邮件附件?

时间:2018-05-03 13:38:12

标签: javascript promise

我从这里提取以下代码段:

https://github.com/chadxz/imap-simple

imaps.connect(config).then(function (connection) {

connection.openBox('INBOX').then(function () {

    // Fetch emails from the last 24h
    var delay = 24 * 3600 * 1000;
    var yesterday = new Date();
    yesterday.setTime(Date.now() - delay);
    yesterday = yesterday.toISOString();
    var searchCriteria = ['UNSEEN', ['SINCE', yesterday]];
    var fetchOptions = { bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE)'], struct: true };

    // retrieve only the headers of the messages
    return connection.search(searchCriteria, fetchOptions);
}).then(function (messages) {

    var attachments = [];

    messages.forEach(function (message) {
        var parts = imaps.getParts(message.attributes.struct);
        attachments = attachments.concat(parts.filter(function (part) {
            return part.disposition && part.disposition.type.toUpperCase() === 'ATTACHMENT';
        }).map(function (part) {
            // retrieve the attachments only of the messages with attachments
            return connection.getPartData(message, part)
                .then(function (partData) {
                    return {
                        filename: part.disposition.params.filename,
                        data: partData
                    };
                });
        }));
    });

    return Promise.all(attachments);
}).then(function (attachments) {
    console.log(attachments);
    // =>
    //    [ { filename: 'cats.jpg', data: Buffer() },
    //      { filename: 'pay-stub.pdf', data: Buffer() } ]
});

在使用两封电子邮件和两个附件测试此代码段时,最终结果将打印一个包含四个附件的数组。

如何更改代码,以便为每封仅包含该电子邮件附件的电子邮件获取单独的数组?

1 个答案:

答案 0 :(得分:0)

您可以尝试以下操作:

messages.forEach(function (message) {
      var parts = imaps.getParts(message.attributes.struct);
                                      //concat array to attachments
      attachments = attachments.concat([parts.filter(function (part) {
          return part.disposition && part.disposition.type.toUpperCase() === 'ATTACHMENT';
      }).map(function (part) {
          // retrieve the attachments only of the messages with attachments
          return connection.getPartData(message, part)
              .then(function (partData) {
                  return {
                      filename: part.disposition.params.filename,
                      data: partData
                  };
              });
      })]/**close bracket for concat array */);
});

return Promise.all(//attachments is array of arrays
  attachments.map(
    attachments=>Promise.all(attachments)
  )
)

以下是使用map:

的方法
Promise.all(
  messages.map(
    message=>
      Promise.all(
        imaps.getParts(message.attributes.struct).filter(
          part=>
            part.disposition && part.disposition.type.toUpperCase() === 'ATTACHMENT'
        ).map(
          part=>
            connection.getPartData(message, part)
            .then(
              partData=>({
                filename: part.disposition.params.filename,
                data: partData
              })
            )

        )
      )
  )
)