我想使用执行函数的同步操作promise.我有循环,将要插入的数据传递给insert函数,插入一行后我想检查否.行中存在行,因此我正在执行select操作.
但问题是,如果有3条记录,那么它会插入所有3条记录,之后我的select函数被执行.我想要的是插入一个记录选择函数后调用.
这是我的伪代码,因为整个代码涉及很多操作
for(var i=0; data.length ; i++){
self.executeFeedbackTrack(data);
}
executeFeedbackTrack:function(callInfo){
var self=this;
return self.insertFeedbackTrack(callInfo).then(function(data){
console.log("insertFeedbackTrack status "+status);
return self.getFeedbackTrack();
});
},
getFeedbackTrack :function(){
return new Promise(function(resolve,reject){
var objDBFeedbackTrack = new DBFeedbackTrack();
objDBFeedbackTrack.selectFeedbackTrack(function(arrayCallRegisters){
if(arrayCallRegisters){
console.log("notification.js no. of feedbacks "+arrayCallRegisters.length);
resolve(arrayCallRegisters.length);
}
});
});
},
insertFeedbackTrack :function(callInfo){
return new Promise(function(resolve,reject){
var objDBFeedbackTrack = new DBFeedbackTrack();
objDBFeedbackTrack.insertFeedbackTrack(callInfo.callNumber,callInfo.callServiceType,function(status){
resolve(status);
$('#loader').hide();
});
});
}
Run Code Online (Sandbox Code Playgroud)
之前的答案很好,但如果您使用的是nodejs或babel,或者您只使用现代浏览器.你可以使用async-await对,它是es8的东西.
let insertFeedbackTrack = function(){ return new Promise(/***/)};
let getFeedbackTrack = function(){ return new Promise(/***/)};
let processResult = async function(data){
let feedbacks = [];
for(let i=0;i<data.length;i++){
let insertedResult = await insertFeedbackTrack(data[i]);//perhaps you will return an id;
let feedbackTrack = await getFeedbackTrack(insertedResult.id);
feedbacks.push(feedbackTrack);
}
return feedbacks;
}
processResult(data).then(/** do stuff */)
Run Code Online (Sandbox Code Playgroud)
在我看来,这是由执行一系列异步插入引起的,并假设在执行之前调用了getof insert n(a 内部.then())insert n+1。但是,我不知道在 JavaScript 中有任何这样的保证;我所熟悉的是then n将在之后调用insert n,而不是在之前调用insert n+1。
我的建议是避免这种混合传统和基于回调的代码,而是将迭代步骤放在getFeedbackTrack().then. 假设对问题的这种理解是正确的,那么应该可以使用以下内容:
function iterate(i) {
if (i < data.length) {
obj.insertFeedbackTrack(data[i]).then(function(insertResult) {
self.getFeedbackTrack().then(function(getResult) {
// this line is the important one, replacing the `for` loop earlier
iterate(i+1);
});
});
}
}
iterate(0);
Run Code Online (Sandbox Code Playgroud)
通过这样做,您将保证insert在当前select成功执行之前不会发生下一个元素。
自然地,您可能还想重构它以使用链式.then而不是嵌套式;我使用嵌套而不是链接来强调回调的顺序。
这可以通过使用一个非常方便的 JS 库Ramda来解决。概念是使用两种方法,一种是,R.partial另一种是R.pipeP。
首先从您的data数组创建一个 Promise 数组,如下所示。
var promises = data.map(function(i) {
return R.partial(sample, [i])
});
Run Code Online (Sandbox Code Playgroud)
然后你可以把这个promise传递给R.pipeP,这样就可以依次执行了。像下面这样。
var doOperation = R.pipeP.apply(this, promises)
Run Code Online (Sandbox Code Playgroud)
请执行以下所附代码片段。
var promises = data.map(function(i) {
return R.partial(sample, [i])
});
Run Code Online (Sandbox Code Playgroud)
var doOperation = R.pipeP.apply(this, promises)
Run Code Online (Sandbox Code Playgroud)
所以在你的情况下,代码将如下所示
var promises = data.map(function(i) {
return R.partial(self.executeFeedbackTrack, [i])
});
var doOperation = R.pipeP.apply(this, promises)
doOperation();
Run Code Online (Sandbox Code Playgroud)