【发布时间】:2016-10-16 19:25:45
【问题描述】:
我根据一些事情从客户端向服务器进行了多次调用,我需要它们等到一个调用完成并在下一个调用开始之前返回一个值。这是我目前正在做的一个小例子:
客户:
function doOrder() {
var addDevices = Template.instance().addDevices.get();
if (addLicense) {
createCustomer();
}
if (addDevices) {
var maintProrate = Session.get('maintProrate');
var deviceCharge = (deviceFee * addDevices);
doCharge(deviceCharge, 'DEVICES', 'deviceCharge', 'chargeMaintFee');
}
}
function createCustomer() {
var stripeArgs = Helpers.client.stripeArgs('form');
Meteor.call('stripe', 'customers', 'create', stripeArgs, function(err, response){
if (err) {
console.log(err);
Bert.alert(err, 'danger');
} else {
Session.set('customerInfo', response);
Session.set('customerId', response.id);
}
});
}
function doCharge(amount, description, storeKey) {
var chargeArgs = {
amount: amount,
currency: 'usd',
customer: Session.get('customerId'),
description: description
};
Meteor.call('stripe', 'charges', 'create', chargeArgs, function(err, response){
if (err) {
console.log(err);
Bert.alert(err, 'danger');
} else {
Session.set(storeKey, response);
}
});
}
服务器:
Meteor.methods({
stripe(func1, func2, arg1) {
check( func1, String );
check( func2, String );
check( arg1, Match.OneOf(Object, String));
var func = Meteor.wrapAsync(Stripe[func1][func2], Stripe[func1]);
return func(arg1, {});
},
stripe2(func1, func2, arg1, arg2) {
check( func1, String );
check( func2, String );
check( arg1, Match.OneOf(Object, String));
check( arg2, Match.OneOf(Object, String));
var func = Meteor.wrapAsync(Stripe[func1][func2], Stripe[func1]);
return func(arg1, arg2, {});
}
});
所以如果addLicense 和addDevices 都在doOrder 函数期间设置,createCustomer 和doCharge 都将运行。我需要的是 createCustomer 函数在运行 doCharge 函数之前完成并返回一个值。
我知道我可以将doCharge 函数放在createCustomer 函数的回调中,但我还有更多函数需要运行,所以我想避免callback hell。
我使用Meteor.wrapAsync 认为可以做到但没有骰子。我仍然从 API 获得返回值,但它们都是同时发生的。
有什么想法吗?提前谢谢你。
【问题讨论】:
-
它可以是顺序的而不是同步的。您不希望 xhr 调用是同步的。而且你可以通过简单地提供更多功能或有效地使用 Promise 来避免回调地狱。
-
@KevinB 我想我不明白。我以为这两个意思是一样的。
createCustomer函数返回一个值,我需要将其传递给doCharge函数。然而,doCharge函数与createCustomer函数同时被调用,因此从 API 返回错误。 -
同步 ajax 请求会阻塞事件循环,直到请求完成,这会使 ajax 请求按顺序执行,但它也会使您的页面在所有请求都完成之前看起来已损坏/无响应,这很糟糕。
-
我真的可以建议这种事情的承诺。您的代码基本上会变得类似于
createCustomer.then(doChange)Meteor,甚至似乎有几个 Promise 库可供选择。粗略地说,它们只是一种方便的方式来构建多个回调,而不会出现厄运金字塔。 :) -
另外,如果我有更多的功能要运行,我会直接链接承诺吗?
createCustomer.then(doCharge).then(updateSubscription).then(finishOrder);?
标签: javascript node.js meteor stripe-payments