Javascript承诺 - 检索结果

时间:2016-04-13 02:58:25

标签: javascript promise

我想检索下面一系列承诺的结果并将其存储到变量中,以便我可以在此链之外使用它。话虽这么说,我继续得到错误或变量出来未定义。

这是系列:

我已尝试将promises存储在变量中,即var customerToken = //下面的代码。但是,customerToken是未定义的,因为promises在变量设置之后结束。

var Stripe = StripeAPI('sk_test_key');

Stripe.customers.create({
  email: Meteor.user().emails[0].address,
  description: "SIDIM 2016",
  source: stripeToken
}).then(function(customer) {

  return Stripe.tokens.create({
    customer: customer.id
  }, {stripe_account: "acct_XXXYYYZZZ"});

}).then(function(token) {

  console.log(token);

  var charge = Stripe.customers.create({
    email: Meteor.user().emails[0].address,
    description: "SIDIM 2016",
    source: token.id
  }, {stripe_account: "acct_XXXYYYZZZ"});

  console.log(charge);

}).then(function(charge) {

  return Stripe.charges.create({
    amount: total,
    currency: 'usd',
    customer: charge.id
  }, {stripe_account: "acct_XXXYYYZZZ"});

}).catch(function(err) {
  // Deal with an error
});

2 个答案:

答案 0 :(得分:0)

您可以return来自每个.then()的值,访问链后的.then()的值

var customerTokens = Promise.resolve()
.then(function() {
    // do stuff
    var customerId = 1;
    return customerId; // return `customerId` here
})
.then(function(id) {
    // do stuff
    return id // return `id` : `customerId` here
})
.then(function(id) {
    // do stuff
    var chargeId = 2;
    return [id, chargeId]; // return both `customerId`:`id` and `chargeId`
})
.catch(function(err) {

});

customerTokens
.then(function(ids) {
    console.log(ids) // access `customerId`, `chargeId` here
});

或者,如果Stripe方法同时使用.then() customer.idcharge.id返回,则可以将Stripe方法传递给同时推送Promise的函数{1}}方法和Stripecustomer.id向数组返回的{1}}值,其中charge.id个方法返回Promise个值Stripe } charge.idcustomer.id将在.then()链接到customerTokens时可用。

var arr = [
  [],
  []
];

var Stripe = function(val) {
  return new Promise(function(resolve) {
    var d = Math.random() * 3000;
    setTimeout(function() {
      arr[0].push({
        StripeData: d // `Stripe` method data
      });
      if (val) {
        arr[1].push(val)
      }
      resolve(arr)
    }, d)
  })
}

var customerTokens = Promise.resolve()
.then(function() {
    // do stuff
    var customerId = 1;
    return Stripe({
      customerId: customerId
    }); // pass `customerId` here
})
.then(function(id) {

    // do stuff
    return Stripe() //
})
.then(function(id) {
    // do stuff
    var chargeId = 2;
    return Stripe({
      chargeId: chargeId
    }); // pass `customerId`
})
.catch(function(err) {

});

customerTokens
.then(function(data) {
    var ids = data[1];
    // access `customerId`, `chargeId` here at `data[1]`
    console.log("complete", data, JSON.stringify(ids))
});

您还可以使用Promise.all(),过滤所有结果.then()

var arr = [
  [],
  []
];

var Stripe = function(val) {
  return new Promise(function(resolve) {
    var d = Math.random() * 3000;
    setTimeout(function() {
      arr[0].push({
        StripeData: d // `Stripe` method data
      });
      if (val) {
        arr[1].push(val)
      }
      resolve(arr)
    }, d)
  })
}

var customerTokens = Promise.all([Stripe({
      customerId: Math.random() * 10
    }), Stripe(), Stripe({
      chargeId: Math.random() * 5
    }).then(function(data) {
  // do stuff
  console.log(data);
  return data // return data
})])

.catch(function(err) {

});

customerTokens
.then(function(data) {
    data.forEach(function(response, index) {
      response[1].forEach(function(ids) {
        console.log(ids) // filter `customerId`, `chargeId` 
      })
    })
});

答案 1 :(得分:0)

丑陋但简单的解决方案是使用(有点)全局变量:

NSUserDefaults *userDef =[NSUserDefaults standardUserDefaults];
    [userDef setInteger:1 forKey:@"poiPosition"];
//        [userDef setObject:@"aa" forKey:@"poiPosition"];
    [userDef synchronize];

更优雅的方法是使用上下文,并将其作为此属性传递到promise链中:

var customerId;

Stripe.customers.create({...}).then(function(customer){
    customerId = customer.id;
    ...

Bergi's answer

中详细了解此解决方案

执行此操作的最佳方法可能是使用async promises,但您可能需要等到ES7:

function getExample() {
    var ctx = {};
    return promiseA(…)
    .then(function(resultA) {
        this.resultA = resultA;
        // some processing
        return promiseB(…);
    }.bind(ctx)).then(function(resultB) {
        // more processing
        return // something using both this.resultA and resultB
    }.bind(ctx));
}