我正在创建一个React应用程序,它涉及对一些webapi REST服务的多次调用来完成我的工作。应用程序的一部分是一些请求的批准流程。可以使用包含以下内容的UI创建这些流的特定角色:
我所做的是允许用户使用Javascript(主要是数组操作)进行更改,同时使用操作和相应数据填充actionbuffer数组。例如
this.actionsBuffer.push({
action: "ADD_STEP",
data: next
});
当用户对此安排感到满意时,她可以按“接受”按钮。它的作用是迭代actionsBuffer数组并执行由action字段确定的相应REST服务。
我知道我的描述可能看起来过于详细,但我希望您了解背景。
问题: 我现在的问题是,由于调用是异步的,我如何保证操作将按此顺序执行。
一些代码段:
迭代并调用determineAction
onAccept: function (e) {
e.preventDefault();
var self = this;
//console.log("Gonna save:",JSON.stringify(this.state.workflow));
var ret=null;
// First we do actions in actionsBuffer
for(var i=0;i<this.actionsBuffer.length;i++)
{
ret = self.determineAction(this.actionsBuffer[i]);
if (ret==false)
break;
else
this.actionsBuffer.splice(i,1);
ret=null;
}
this.saveAll();
},
并确定行动。请原谅调试控制台消息
determineAction: function (action) {
var url="";
var verb="";
switch(action.action)
{
case "ADD_STEP":
delete action.data.ActorList;
url=this.props.server+"/workflows/"+this.props.workflowid+"/steps";
verb="POST";
break;
case "DELETE_STEP":
url=this.props.server+"/workflows/"+this.props.workflowid+"/delete/";
verb="POST";
break;
}
console.log("Going to call url:",url," with varb:",verb," and data:",action.data);
$.ajax({
type: verb,
url: url,
data: JSON.stringify(action.data),
processData:false,
contentType: 'application/json'
})
.success(function(data) {
return true;
//self.props.onclose(self.state.workflows.WorkflowId);
})
.error(function(jqXhr) {
console.log(jqXhr);
return false;
});
},
答案 0 :(得分:0)
您不是在等determineAction
完成。让它返回一个承诺,并在你调用它的地方等待它。你的循环也必须是异步的。我创造的尝试可能并不完全符合您的需要,但会向您显示您应该移动的方向。
onAccept: function (e) {
e.preventDefault();
var self = this;
var ret=null;
// First we do actions in actionsBuffer
var i = 0;
function makeRequest() {
self.determineAction(self.actionsBuffer[i]).success(function() {
i++;
if (i >= (self.actionsBuffer.length) {
self.saveAll();
} else {
makeRequest();
}
}).error(function(){
self.saveAll();
})
}
makeRequest()
this.saveAll();
},
determineAction: function (action) {
var url="";
var verb="";
switch(action.action)
{
case "ADD_STEP":
delete action.data.ActorList;
url=this.props.server+"/workflows/"+this.props.workflowid+"/steps";
verb="POST";
break;
case "DELETE_STEP":
url=this.props.server+"/workflows/"+this.props.workflowid+"/delete/";
verb="POST";
break;
}
console.log("Going to call url:",url," with varb:",verb," and data:",action.data);
return $.ajax({
type: verb,
url: url,
data: JSON.stringify(action.data),
processData:false,
contentType: 'application/json'
});
},
答案 1 :(得分:0)
而不是与for
循环同步迭代您的操作数组。相反,将其视为一个队列。
这是一个简单的例子。
function processActions(actionQueue) {
if(actionQueue.length == 0) return;
// take the first action from the queue
var action = actionQueue[0];
// assuming determineAction() returns a promise
determineAction(action)
.then(function() {
var remainingActions = actionQueue.slice(1);
// we know this action has completed, so we can pass
// the remaining actions to be processed
processActions(remainingActions);
});
}