流星回调天堂在另一个回调后呼叫回叫

时间:2015-02-17 21:29:48

标签: javascript node.js meteor callback

我已经设置了3个需要彼此运行的功能

我已经正确设置了我的回调,能够像这样在functionOne之后调用functionTwo ...

functionOne(functionTwo) // this is fine

如何在functionTwo之后调用functionThree?

我试过functionOne(functionTwo(functionThree)),但这是错误的

我的代码

   var functionOneAsync = function(callback) {
     request.post('http://www.goodreads.com/oauth/access_token', {
     oauth: {consumer_key: 'somekey',
            consumer_secret: 'somesecretkey',
            token: oauthToken,
            token_secret: oauthTokenSecret}
  },
  function (error, response, body){
    if (!error && response.statusCode === 200) {
      var perm_data = querystring.parse(body)
      var accessToken = perm_data.oauth_token
      var tokenSecret = perm_data.oauth_token_secret
      console.log('exch done')
      return callback(null, accessToken, tokenSecret)
    }
    else {
      callback(error)
    }
  })
}
var functionOneAsyncSync = Meteor.wrapAsync(functionOneAsync);

var functionTwoAsync = function(error, accessToken, tokenSecret, callback) {
  request.get('https://www.goodreads.com/api/auth_user', {
    oauth: {consumer_key:'somekey',
            consumer_secret:'somesecretkey',
            token: accessToken,
            token_secret: tokenSecret
            }
  },
  function (error, response, body) {
    if (!error && response.statusCode === 200) {
      var options = {
        object: true,
        reversible: false,
        coerce: true,
        sanitize: true,
        trim: true,
        arrayNotation: false
      }
      var bodyToJson = parser.toJson(body, options)
      var goodreadsUserId = bodyToJson.GoodreadsResponse.user.id
      console.log('user id done' + goodreadsUserId)
      return callback(null, accessToken, tokenSecret, goodreadsUserId)
      }
    else {
      return callback(error)
    }
  })
}
var functionTwo = Meteor.wrapAsync(functionTwoAsync);



 var functionThreeAsync = function(error, accessToken, tokenSecret, goodreadsUserId) {
  if (error) {
    console.log('error in storing')
    console.log(error)
  }
  else {
    Meteor.users.update({_id: Meteor.userId()}, {$set: {'profile.goodreads.accessToken': accessToken, 'profile.goodreads.tokenSecret': tokenSecret, 'profile.goodreads.userID': goodreadsUserId}});
    console.log('reached storing in user collection')
  }
}
var functionThree = Meteor.wrapAsync(functionThreeAsync);

1 个答案:

答案 0 :(得分:1)

Meteor为回调地狱提供了很好的解决方案。

如果您已经使用Meteor.wrapAsync包装函数,那么您应该能够像这样运行它们(伪代码):

try {
 var resultOne = functionOne();
 var resultTwo = functionTwo(resultOne.accessToken, resultOne.tokenSecret, ...)
 var resultThree = functionThree(resultOne.accessToken, resultOne.tokenSecret, ...)
} catch ( e ) {
   console.error('functionOne or functionTwo or functionThree thrown error = ', e);
} 

如果你想像上面那样运行它们,你需要以这样的方式实现你的功能:

var functionTwoAsync = function(accessToken, tokenSecret, callback) {
  request.get('https://www.goodreads.com/api/auth_user', {
    oauth: {...}
  },
  function (error, response, body) {
    if (!error && response.statusCode === 200) {

      // IMPORTANT !!!
      return callback(
            null, 
            { 
              accessToken : accessToken,
              tokenSecret : tokenSecret,
              goodreadsUserId : goodreadsUserId
            }
      )
    } else {
      return callback(error)
    }
  })
}
var functionTwo = Meteor.wrapAsync(functionTwoAsync);