Это выглядит как отличное применение для Promise объекта.Обещания улучшают возможность повторного использования функций обратного вызова, обеспечивая общий интерфейс для асинхронных вычислений. Вместо того, чтобы каждая функция принимала параметр обратного вызова, Promises позволяет вам инкапсулировать асинхронную часть вашей функции в объект Promise. Затем вы можете использовать методы Promise (Promise.all, Promise.prototype.then), чтобы объединить ваши асинхронные операции. Вот как ваш пример переводит:
// Instead of accepting both a url and a callback, you accept just a url. Rather than
// thinking about a Promise as a function that returns data, you can think of it as
// data that hasn't loaded or doesn't exist yet (i.e., promised data).
function getData(url) {
return new Promise(function (resolve, reject) {
// Use resolve as the callback parameter.
});
}
function parseData(data) {
// Does parseData really need to be asynchronous? If not leave out the
// Promise and write this function synchronously.
return new Promise(function (resolve, reject) {
});
}
getData("someurl").then(parseData).then(function (data) {
console.log(data);
});
// or with a synchronous parseData
getData("someurl").then(function (data) {
console.log(parseData(data));
});
Кроме того, я должен отметить, что в настоящее время обещают отличную поддержку браузера. К счастью, вы покрыты, так как существует множество полиполков, таких как this one, которые обеспечивают большую часть той же функциональности, что и родные обещания.
Редактировать:
В качестве альтернативы, вместо изменения Function.prototype, как о реализации способа цепи, который принимает в качестве входных данных список асинхронных функций и начальное значение и трубы, что начальное значение через каждую функцию асинхронном:
function chainAsync(seed, functions, callback) {
if (functions.length === 0) callback(seed);
functions[0](seed, function (value) {
chainAsync(value, functions.slice(1), callback);
});
}
chainAsync("someurl", [getData, parseData], function (data) {
console.log(data);
});
Редактировать снова:
решение, представленное выше, далеко от надежного, если вы хотите более обширное решение проверить что-то вроде https://github.com/caolan/async.
'getData.then()' не будет включать вызов функции 'getData()'. Думаю, вы ошибетесь. – Pointy
Могу ли я спросить, почему вы не просто используете библиотеку обещаний (например, q)? https://github.com/kriskowal/q – Antiga
FYI, ['.promisify()'] (https://github.com/petkaantonov/bluebird/blob/master/API.md#promisepromisifyfunction-nodefunction--dynamic -receiver --- function) в таких библиотеках, как Bluebird, сделает все это для вас, а затем вы сделаете что-то вроде 'getDataAsync (...). then (parseDataAsync)'. Если вы хотите реализовать эту функциональность самостоятельно, не используя стороннюю библиотеку, вы можете посмотреть, как она реализована в Bluebird и учиться на этом. – jfriend00