Javascript 如何同步地从客户端调用服务器?
我从客户机向服务器进行了几次调用,这取决于几件事,我需要他们等到一次调用完成,并在下一次调用开始之前返回一个值。下面是我目前正在做的一个小例子: 客户: 服务器: 因此,如果Javascript 如何同步地从客户端调用服务器?,javascript,node.js,meteor,stripe-payments,Javascript,Node.js,Meteor,Stripe Payments,我从客户机向服务器进行了几次调用,这取决于几件事,我需要他们等到一次调用完成,并在下一次调用开始之前返回一个值。下面是我目前正在做的一个小例子: 客户: 服务器: 因此,如果addLicense和addDevices都是在doOrder功能期间设置的,则createCustomer和doCharge都将运行。我需要的是createCustomer函数在运行doCharge函数之前完成并返回一个值 我知道我可以将doCharge函数放在createCustomer函数的回调中,但我还有很多函数
addLicense
和addDevices
都是在doOrder
功能期间设置的,则createCustomer
和doCharge
都将运行。我需要的是createCustomer
函数在运行doCharge
函数之前完成并返回一个值
我知道我可以将doCharge
函数放在createCustomer
函数的回调中,但我还有很多函数需要按顺序运行,因此我希望避免
我曾经用Meteor.wrapAsync认为它可以做到,但没有骰子。我仍然从API获得返回值,但它们都同时发生
有什么想法吗?提前谢谢。正如@MichelFloyd建议的那样,我最终将所有调用移到了服务器端方法中,这样只需要来自客户端的一个调用。它可以是连续的,而不需要同步。您不希望xhr调用是同步的。你可以通过简单的增加功能或者有效地使用承诺来避免回调地狱。@KevinB我想我不明白。我想这两个词的意思是一样的。
createCustomer
函数返回我需要在doCharge
函数中传递的值。但是,doCharge
函数与createCustomer
函数同时被调用,从而从API返回错误。同步ajax请求会阻塞事件循环,直到请求完成,这将使ajax请求连续,但这也会让你的页面在所有请求完成之前看起来都是破损/无响应的,这很糟糕。我真的可以为这类事情提供建议。您的代码基本上与createCustomer类似。然后(doChange)
Meteor甚至似乎有几个promise库可供选择。粗略地说,它们只是构造多个回调的一种方便方法,而不必经历厄运金字塔。:)另外,如果我有更多的函数要运行,我会把承诺链起来吗<代码>createCustomer.then(doCharge).then(updateSubscription).then(finishOrder)代码>?
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, {});
}
});