简体   繁体   English

承诺不返价值

[英]Promise not returning value

I have a node issue where I'm using the imap module, and I am trying to return a promise. 我在使用imap模块时遇到一个节点问题,我想返回一个承诺。 I have created a Promise.method() using bluebird. 我已经使用bluebird创建了Promise.method() The code is actually available at: https://github.com/dkran/email-thinky-test/ 该代码实际上位于: https : //github.com/dkran/email-thinky-test/

So my issue is I have this file performing this: 所以我的问题是我让这个文件执行此操作:

//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

and then another little file doing this: 然后另一个小文件这样做:

//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)
    })
  })
})

At the bottom of the helper file when the 'end' event triggers, and the console.log goes off, it says I have 9 messages (which is true.) if I log the messages there instead it shows them all in the object. 当'end'事件触发并且console.log关闭时,在帮助程序文件的底部,它说我有9条消息(这是正确的)。如果我在其中记录消息,它将全部显示在对象中。 but they never get returned it's always undefined. 但是他们永远不会得到返回,它始终是不确定的。 Why is this? 为什么是这样? All of my other callbacks I converted seemed to work fine. 我转换的所有其他回调似乎都正常运行。

exact output I get is: 我得到的确切输出是:

res: undefined

mail: undefined

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

Messages: 9

You don't want to use Promise.method in this situation. 在这种情况下,您不想使用Promise.method Just return a promise that gets resolved somewhere along all of those callbacks. 只需返回一个在所有这些回调中都得到解决的承诺即可。

 //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 

As per my and @Bergi's conversation, I realized I just have to return the whole chain of promises. 根据我和@Bergi的交谈,我意识到我只需要返回整个承诺链。 like so, and it works: 像这样,它的工作原理是:

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

Now, the promise returns the property like it should have. 现在,promise将返回应有的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM