2016-06-09 8 views
0

Я хотел бы показать, насколько чистые объекты, отложенные jQuery, могут сделать код вместо использования «callback hell».jQuery Promise/Deferred nicer Код, чем callbacks? Как это сделать?

У меня нет возможности переключиться на Javascript's Promises.

Вот "плохой" код:

/* Callback Hell !? */ 

// Main 

var stringToProcess = "1,2,3,4,5,6"; 

console.debug("Main Stack: start"); 

convertStringToArray(stringToProcess, function (convertedString){ 
    convertToObject(convertedString, function(objectOfStrings){ 
     resetObjectValues(objectOfStrings, function(object){ 
      console.debug(object); 
     }); 
    }); 
}); 

console.debug("Main Stack: end"); 



// Functions 

function resetObjectValues(object, callback){ 
    for(var key in object){ 
     object[key] = "X"; 
    } 

    setTimeout(function thirdcb(){ 
     callback(object); 
    }, 500); 
} 

function convertToObject(string, callback){ 
    var object = {}; 
    string.map(function(current, index){ 
     object[index] = current; 
    }); 

    setTimeout(function secondcb(){ 
     callback(object); 
    }, 500); 
} 

function convertStringToArray(string, callback){ 
    var delimiter = ","; 
    var arrayString = string.split(delimiter); 

    setTimeout(function firstcb(){ 
     callback(arrayString); 
    }, 500); 

} 

И вот как я пытался сделать это лучше:

/* Promise Heaven... */ 


// Main 

var stringToProcess = "1,2,3,4,5,6"; 

console.debug("Main Stack: start"); 

var promise; 
promise = convertStringToArray(stringToProcess); 
promise.done(function(string){ 
    promise = convertToObject(string); 
    promise.done(function(object){ 
     promise = resetObjectValues(object); 
     promise.done(function(object){ 
      console.debug(object); 
     }) 
    }) 
}); 

console.debug("Main Stack: end"); 

// Functions 

function resetObjectValues(object, callback){ 
    var deferred = $.Deferred(); 
    for(var key in object){ 
     object[key] = "X"; 
    } 

    setTimeout(function thirdcb(){ 
     deferred.resolve(object); 
    }, 500); 

    return deferred.promise(); 
} 

function convertToObject(string){ 
    var deferred = $.Deferred(); 
    var object = {}; 
    string.map(function(current, index){ 
     object[index] = current; 
    }); 

    setTimeout(function secondcb(){ 
     deferred.resolve(object); 
    }, 500); 

    return deferred.promise(); 
} 

function convertStringToArray(string){ 
    var deferred = $.Deferred(); 
    var delimiter = ","; 
    var arrayString = string.split(delimiter); 

    setTimeout(function firstcb(){ 
     deferred.resolve(arrayString); 
    }, 500); 

    return deferred.promise(); 

} 

... печально код .done() выглядит почти так же плохо, как «ад». Я не могу понять, как правильно связывать обещания/отсрочки. Я видел учебники, где они делают это без аргументов для вызовов функций. Но у меня есть аргументы, чтобы бросить - так, как ладить с этим?

+0

Это ваш код только для демонстрационных целей, так как он не должен быть асинхронным вообще. –

+0

Вы должны использовать ['then'] (http://api.jquery.com/deferred.then/) вместо' done', чтобы вы могли [сгладить цепочку] (http: // stackoverflow. com/a/22000931/1048572): 'convertStringToArray (stringToProcess). then (convertToObject). then (resetObjectValues) .then (console.debug.bind (консоль));' – Bergi

ответ

2

Сцепление обещаний должно выглядеть примерно так:

convertStringToArray(stringToProcess) 
    .then(function(string){ 
    return convertToObject(string); 
    }) 
    .then(function(object){ 
    return resetObjectValues(object); 
    }) 
    .then(function(object){ 
    console.debug(object); 
    }); 

В принципе каждая функция (обратный вызова) возвращает новое обещание, которое затем может быть использовано для присоединения других обработчиков к нему. Таким образом, вам не требуется вложение обратных вызовов, как в вашем коде.

+0

Выглядит хорошо! – xetra11

+1

За исключением того, что использование 'done' не работает. Только метод 'then' возвращает новые обещания и цепочки. – Bergi

+1

@ Bergi Изменено. – Sirko