2017-07-12 196 views
2

我想知道是否有更好的方法在JavaScript中执行异步循环?我一直在使用下面的递归方法,但我觉得可能有一个更清晰的方法。任何链接/建议将不胜感激。由于JavaScript异步循环

var titles = ['Test 1', 'Test 2', 'Test 3']; 
var i = 0; 
addColumns(); 

function addColumns() { 
    if (i < titles.length) { 
     var data = { 
      '__metadata': { 'type': 'SP.FieldText' }, 
      'FieldTypeKind': 3, 
      'Title': titles[i], 
      'MaxLength': '22' 
     }; 

     postToSP.createColumns(baseURL, listName, data) 
      .then(function() { 
       i++; 
       addColumns(); 
      }) 
      .catch(function(e){ 
       console.log('Error: ' + e); 
      }) 
    } else { 
     return; 
    }; 
}; 
+1

为什么这些调用需要按顺序执行?命令是重要的吗? –

+0

它们不需要按顺序排列,但ShrePoint在尝试同时写入全部3个时会引发错误 –

+1

好的。那么肯定会在我的回答中使用第一种模式,因为下一次呼叫将不会被启动,直到前一次往返。第二次试图同时做到这一点。 –

回答

4

假设处决值无关(即一个不依赖于前一个的值),但连续的(他们必须往返于确定的顺序完成):

var allDone = titles.reduce((prev, title) => { 
    var data = { 
    '__metadata': { 'type': 'SP.FieldText' }, 
    'FieldTypeKind': 3, 
    'Title': title, 
    'MaxLength': '22' 
    }; 
    return prev.then(_ => postToSP.createColumns(baseURL, listName, data)); 
}, Promise.resolve(true)); 

这将排队一系列ajax请求,只有在前一个请求完成后才会启动。错误处理作为练习留给读者。如果调用必须按照一定的顺序来完成,这是干净多了这种方式:

let allDone = Promise.all(titles.map(title => postToSP.createColumns...)); 

不管怎样,现在你已经有了一个单一的承诺,将解决当所有的异步调用完成。