首页 文章

承诺不归还 Value

提问于
浏览
0

我有一个节点问题,我正在使用 imap 模块,我正在尝试返回一个承诺 . 我用蓝鸟创建了一个 Promise.method() . 该代码实际上位于:https://github.com/dkran/email-thinky-test/

所以我的问题是我有这个文件执行此操作:

//file: ./imap/helper.js 
var Imap = require('imap'),
    Promise = require('bluebird'),
    imap = require('../util/imap');

exports.parseMailbox = Promise.method(function(boxName){
  boxName = boxName || 'INBOX'
  imap.openBoxAsync(boxName, false).then(function(inbox){
    var messages = [], newMessage = {};
    imap.searchAsync(['ALL']).then(function(results){
      var f = Promise.promisifyAll(imap.fetch(results, {
        bodies: ['HEADER.FIELDS (FROM TO CC BCC SUBJECT)','TEXT'],
        struct: true
      }));

      f.on('message', function(msg, seqno) {
        newMessage = {}

        msg.on('body', function(stream, info) {
          //When we get a message, append the header to header, text to body.
          stream.on('data', function(chunk){
            if (info.which !== 'TEXT')
              newMessage.rawHeader += chunk.toString('utf8')
            else
              newMessage.body += chunk.toString('utf8')
          })

          //When stream is done, strip the unparsable characters at the beginning before parsing.
          //NOTE: I'm not actually sure what these unparseable characters actually are
          //but this all works kosher.
          stream.once('end', function() {
            if (info.which !== 'TEXT'){
              newMessage.rawHeader = newMessage.rawHeader.replace(/^undefined/, '')
              newMessage.header = Imap.parseHeader(newMessage.rawHeader)
            }
            if(newMessage.body)
              newMessage.body = newMessage.body.replace(/^undefined/, '')
          })
        })

        msg.once('attributes', function(attrs) {
          newMessage.attrs = attrs
        })

        msg.once('end', function() {
          messages[seqno-1] = newMessage
        })

      });

      f.once('error', function(err) {
        throw err
      });

      return f.onceAsync('end').then(function() {
        console.log('Messages: ' + messages.length)
        return messages
      })
    }).catch(function(e){
      throw e
    })
  }).catch(function(e){
    throw e
  })
})

module.exports = exports

然后另一个小文件这样做:

//file: ./imap/index.js
var imap = require('../util/imap'),
  mail = require('./mail'),
  mailHelpers = require('./helpers');

imap.onceAsync('ready').then(function(){
  imap.getBoxesAsync().then(function(result){
    for(var box in result){
      mail.mailboxes.push(box)
    }
  }).catch(function(e){
    console.log(e)
  }).finally(function(){
    mailHelpers.parseMailbox('INBOX').then(function(res){
      mail.mail = res
      console.log('res: ' + res)
      console.log('mail: ' + mail.mail)
      console.log(mail.mailboxes)
    }).catch(function(e){
      console.log(e)
    })
  })
})

在'end'事件触发时辅助文件的底部,并且console.log关闭,它表示我有9条消息(这是真的 . )如果我在那里记录消息而不是在对象中显示它们 . 但是它们永远不会被归还它总是未定义的 . 为什么是这样?我转换的所有其他回调似乎都运行正常 .

我得到的确切输出是:

res: undefined

mail: undefined

[ 'INBOX', 'Sent Messages', 'Deleted Messages', 'Drafts' ]

Messages: 9

2 回答

  • 0

    在这种情况下,您不想使用 Promise.method . 只需返回一个在所有这些回调中得到解决的承诺 .

    //file: ./imap/helper.js 
    var Imap = require('imap'),
      Promise = require('bluebird'),
      imap = require('../util/imap');
    
    exports.parseMailbox = function(boxName) {
      return new Promise(function(resolve, reject) {
    
        boxName = boxName || 'INBOX'
        imap.openBoxAsync(boxName, false).then(function(inbox) {
          var messages = [],
            newMessage = {};
          imap.searchAsync(['ALL']).then(function(results) {
            var f = Promise.promisifyAll(imap.fetch(results, {
              bodies: ['HEADER.FIELDS (FROM TO CC BCC SUBJECT)', 'TEXT'],
              struct: true
            }));
    
            f.on('message', function(msg, seqno) {
              newMessage = {}
    
              msg.on('body', function(stream, info) {
                //When we get a message, append the header to header, text to body.
                stream.on('data', function(chunk) {
                  if (info.which !== 'TEXT')
                    newMessage.rawHeader += chunk.toString('utf8')
                  else
                    newMessage.body += chunk.toString('utf8')
                })
    
                //When stream is done, strip the unparsable characters at the beginning before parsing.
                //NOTE: I'm not actually sure what these unparseable characters actually are
                //but this all works kosher.
                stream.once('end', function() {
                  if (info.which !== 'TEXT') {
                    newMessage.rawHeader = newMessage.rawHeader.replace(/^undefined/, '')
                    newMessage.header = Imap.parseHeader(newMessage.rawHeader)
                  }
                  if (newMessage.body)
                    newMessage.body = newMessage.body.replace(/^undefined/, '')
                })
              })
    
              msg.once('attributes', function(attrs) {
                newMessage.attrs = attrs
              })
    
              msg.once('end', function() {
                messages[seqno - 1] = newMessage
              })
    
            });
    
            f.once('error', function(err) {
              throw err
            });
    
            return f.onceAsync('end').then(function() {
              console.log('Messages: ' + messages.length)
              // just resolve it, lets not worry about returning promises 3 or 4 callbacks deep
              resolve(messages)
            })
          }).catch(function(e) {
            // pass the failure to the promise
            reject(e)
          })
        }).catch(function(e) {
          reject(e)
        })
      })
    }
    
    module.exports = exports
    
  • 0

    根据我和@ Bergi的谈话,我意识到我必须回归整个承诺链 . 像这样,它的工作原理:

    exports.parseMailbox = function(boxName){
      boxName = boxName || 'INBOX'
      return imap.openBoxAsync(boxName, false).then(function(inbox){
      var messages = [], newMessage = {};
        return imap.searchAsync(['ALL']).then(function(results){
          var f = Promise.promisifyAll(imap.fetch(results, {
            bodies: ['HEADER.FIELDS (FROM TO CC BCC SUBJECT)','TEXT'],
            struct: true
          }));
    
      f.on('message', function(msg, seqno) {
        newMessage = {}
    
        msg.on('body', function(stream, info) {
          //When we get a message, append the header to header, text to body.
          stream.on('data', function(chunk){
            if (info.which !== 'TEXT')
              newMessage.rawHeader += chunk.toString('utf8')
            else
              newMessage.body += chunk.toString('utf8')
          })
    
              //When stream is done, strip the unparsable characters at the beginning before parsing.
              //NOTE: I'm not actually sure what these unparseable characters actually are
              //but this all works kosher.
              stream.once('end', function() {
                if (info.which !== 'TEXT'){
                  newMessage.rawHeader = newMessage.rawHeader.replace(/^undefined/, '')
                  newMessage.header = Imap.parseHeader(newMessage.rawHeader)
                }
                if(newMessage.body)
                  newMessage.body = newMessage.body.replace(/^undefined/, '')
              })
            })
    
            msg.once('attributes', function(attrs) {
              newMessage.attrs = attrs
            })
    
            msg.once('end', function() {
              messages[seqno-1] = newMessage
            })
    
          })
    
          f.onceAsync('error').catch(function(err){
            throw err
          })
    
          return f.onceAsync('end').then(function() {
            console.log('Messages: ' + messages.length)
            return messages
          })
        })
      }).catch(function(e){
        throw e
      })
    }
    
    module.exports = exports
    

    现在,承诺会像它应该的那样返回属性 .

相关问题