在循环内使用promise进行顺序调用

Hun*_*unt 14 javascript

我想使用执行函数的同步操作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)

Ale*_*lin 7

之前的答案很好,但如果您使用的是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)


Eth*_*ski 5

在我看来,这是由执行一系列异步插入引起的,并假设在执行之前调用了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而不是嵌套式;我使用嵌套而不是链接来强调回调的顺序。


Vip*_*mar 3

这可以通过使用一个非常方便的 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)