ECMAScript 6 has 'generators' which allow you to easily program in an asynchronous style.
function* myGenerator() { const callback = yield; let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback}); console.log("response is:", response); // examples of other things you can do yield setTimeout(callback, 1000); console.log("it delayed for 1000ms"); while (response.statusText === "error") { [response] = yield* anotherGenerator(); }}To run the above code you do this:
const gen = myGenerator(); // Create generatorgen.next(); // Start itgen.next((...args) => gen.next([...args])); // Set its callback functionIf you need to target browsers that don't support ES6 you can run the code through Babel or closure-compiler to generate ECMAScript 5.
The callback ...args are wrapped in an array and destructured when you read them so that the pattern can cope with callbacks that have multiple arguments. For example with node fs:
const [err, data] = yield fs.readFile(filePath, "utf-8", callback);