基于场景动态生成AJAX请求

简单地说,我正在尝试根据我通过服务器的AJAX请求检索的场景动态生成AJAX请求。

这个想法是:

  1. 服务器为我提供了一个生成AJAX请求的“场景”。
  2. 我根据场景生成一个AJAX请求。
  3. 然后我在循环中一遍又一遍地重复这个过程。

最重要的是我可以根据服务器提供的场景动态更改第二个AJAX请求。

我有这个工作,但我觉得我这样做的方式非常混乱。 有没有更好的方法来思考这个问题? 也许承诺? 如果有人可以请审查这个并提供有关如何清理它的反馈或建议 – 非常感谢。

这是我的代码: http : //jsfiddle.net/6jph0e98/ (请打开控制台以查看所有操作)

作为参考,这里是我正在使用的场景数据:

var scenario = { "base": { "frequency": "5000" }, "endpoints": [ { "method": "GET", "type": "JSON", "endPoint": "https://api.github.com/users/alvarengarichard", "queryParams": { "objectives": "objective1, objective2, objective3" } } ] } 

这是我的2美分: http : //jsfiddle.net/3Lddzp9j/6/ 。

是的,我认为你可以通过链接承诺来更优雅地做到这一点。 所以我想出了我认为你的应用程序做了什么,以及你如何通过链接这些承诺来做到这一点。 有趣的是,某些步骤已经返回promises(jQuery AJAX调用),但其他步骤没有。 对于那些 – 我们必须创建我们自己的承诺,立即解决。 然后是我们在承诺中包含的超时。

此外,我尝试使用一些JS最佳实践,例如通过将它们包装在IIFE中并应用模块模式来将事物排除在全局空间之外 。 这使您的应用程序的整体控制流程变得美观和干净恕我直言:

  var run = function() { getScenario() .then(mapToInstruction) .then(waitForTimeout) .then(callApi) .then(handleResults) .then(run); }; 

并隐藏私有成员并仅暴露run()方法:

  return { // This will expose only the run method // and will keep all other functions private run : run } 

希望它有所帮助 – 让我知道你的想法。 这是完整的来源,评论:

 // First of all - I'm using the javascript module pattern here // this will all be much more easy once ES6 it out, but this will // have to do for now. // Also, I'm importing jQuery into the module as you can see, which // is wrapped inside the IIFE ( Google it ) which keeps things nicely // out of the global scope. var App = (function ($) { // Gets the scenario from the API - $.get is just some syntactic // sugar for $.ajax with GET as method - NOTE: this returns a promise var getScenario = function () { console.log('Getting scenario ...'); return $.get('http://demo3858327.mockable.io/scenario'); }; // The result of the previous promise is passed into the // next as we're chaining. So the data will contain the // result of getScenario var mapToInstruction = function (data) { // We map it onto a new instruction object var instruction = { method: data.endpoints[0].method, type: data.endpoints[0].type, endpoint: data.endpoints[0].endPoint, frequency: data.base.frequency }; console.log('Instructions recieved:'); console.log(instruction); // And now we create a promise from this // instruction so we can chain it var deferred = $.Deferred(); deferred.resolve(instruction); return deferred.promise(); }; // This wraps the setTimeout into a promise, again // so we can chain it var waitForTimeout = function(instruction) { console.log('Waiting for ' + instruction.frequency + ' ms'); var deferred = $.Deferred(); setTimeout(function() { deferred.resolve(instruction) }, instruction.frequency); return deferred.promise(); }; // Final step: call the API from the // provided instructions var callApi = function(instruction) { console.log('Calling API with given instructions ...'); return $.ajax({ type: instruction.method, dataType: instruction.type, url: instruction.endpoint }); }; var handleResults = function(data) { console.log("Handling data ..."); var deferred = $.Deferred(); deferred.resolve(); return deferred.promise(); }; // The 'run' method var run = function() { getScenario() .then(mapToInstruction) .then(waitForTimeout) .then(callApi) .then(handleResults) .then(run); }; return { // This will expose only the run method // and will keep all other functions private run : run } })($); // ... And start the app App.run();