暂停异步循环然后继续处理

时间:2017-04-04 19:38:13

标签: javascript

我想知道是否有更好的方法来执行此代码。我试图处理两个文件并保存在数据库中。我想处理一个Order(父),当它完成时,然后处理子记录。如果数据库锁定某些记录,我等待2秒,然后再试一次。 我让它以这种方式工作,但我想知道如何才能让它变得更好。 附:我不能使用async - 等待

var orderItems = [1, 2, 3];
var tries = 0;

saveOrder()
 .then(function() {
   console.log('Done Order');
   try {
     asyncLoop(orderItems.length, nextItem, success);
   }
   catch(e) { 
     console.log(e); 
   }
 })
 .catch ( console.log );

function nextItem(loop) {
  saveItems(loop.iteration())
  .then((msg) => {
    console.log(loop.iteration());
    loop.next();
  })
  .catch((e) => {
    if (e instanceof String) console.log('Catched !!');
    console.log(e);
    tries = 1;
    waitNTryAgain().then(() => { console.log('Trying again!'); nextItem(loop); });
  });
}

function waitNTryAgain() {
  return new Promise((resolve, reject) => {
    setTimeout( resolve, 2000, 'Done waiting');
  });
}

function success() {
  console.log('Done asyncLoop!');
}

function saveOrder() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 2000, 'Save Order Done!');
  });
}

function saveItems(itemNumber) {
  return new Promise((resolve, reject) => {      
      if (itemNumber == 1 && tries == 0) {
        setTimeout(reject, 4000, 'DbLockedException');
      }
      else {
        setTimeout(resolve, 4000, 'Save Item#: ' + itemNumber + ' Done!');
      }     
  })
}

function asyncLoop(iterations, func, callback) {
  var index = 0;
  var done = false;
  var loop = {
               next: function() {
                      if (done) return;    

                      if (index < iterations) {
                        index++;
                        func(loop);
                      } 
                      else {
                        done = true;
                        callback();
                      }
                    },
               iteration: function() {
                 return index - 1;
               },    
               break: function() {
                 done = true;
                 callback();
               }
             };
  loop.next();
  return loop;
}

2 个答案:

答案 0 :(得分:0)

我能做的最好的改进就是创建一个模块模式:

var AsyncProc = (function(){
	return{
  	orderItems : [1, 2, 3],
    tries : 0,
    init : function()
    {
        this.saveOrder()
        .then(() => {
          console.log('Done Order')
          try
          {
            this.asyncLoop(this.orderItems.length, this.nextItem.bind(this), this.success)
           }
           catch(e) { console.log(e) }
        })
        .catch( console.log );    
    },
    saveOrder : function()
    {
    		return new Promise((resolve, reject) =>{
  				setTimeout(resolve, 2000, 'Save Order Done!')
  		})
    },
    nextItem : function(loop)
    {
      this.saveItems( loop.iteration() )
      .then((msg) => {
        console.log(loop.iteration())
        loop.next();
      })
      .catch((e) =>{
        console.log(e);
        this.tries = 1;
        this.waitNTryAgain().
        then(() => { console.log('Trying again!'); this.nextItem(loop); })
      })
    },
    waitNTryAgain : function()
    {
      return new Promise((resolve, reject) => {
        setTimeout( resolve, 2000, 'Done waiting')
      })
    },
    saveItems : function(itemNumber)
    {
      return new Promise((resolve, reject) =>{

          if (itemNumber == 1 && this.tries == 0)
          {
            setTimeout(reject, 4000, 'DbLockedException');
          }
          else
          {
            setTimeout(resolve, 4000, 'Save Item#: '+itemNumber+' Done!');
          } 
      });
    },    
    success : function()
    {
      console.log('Done asyncLoop!')
    },    
    asyncLoop : function(iterations, func, callback) 
    {
        var index = 0;
        var done = false;
        var loop = 
        {
          next: function() 
          {
            if (done) 	return;

            if (index < iterations) 
            {
              index++;
              func(loop);
            } 
            else 
            {
              done = true;
              callback();
            }
        },
        iteration: function() 
        {
            return index - 1;
        },

        break: function() 
        {
            done = true;
            callback();
        }
      };
      loop.next();
      return loop;
    }	    
  };

})();

AsyncProc.init();

答案 1 :(得分:0)

代码问题 - 您自己正在实施asyncLoop。最好使用一些库。

您可以使用https://github.com/caolan/asynchttp://bluebirdjs.com/docs/api

执行此操作

我更喜欢蓝鸟。它还会为您提供一些更好的方法来处理错误。