流星回调天堂一个又一个回调

meteor callback heaven calling a callback after another 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);

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);