2013-04-05 9 views
12

Powiedzmy chcę przetworzyć niektórych zadań w sposób synchroniczny, więc mam tę funkcję:nie asynchroniczna funkcja realizowana jako jQuery odroczony

function executePromiseQueueSync(queue){ 
    var seed = $.Deferred(), 
     finalPromise; 

    finalPromise = _.reduce(queue, function(memo, promise){ 
     return memo.then(function(){ 
      return promise.funct.apply(null, promise.argmnt); 
     }); 
    }, seed.promise()); 

    seed.resolve(); 
    return finalPromise; 
} 

Teraz mogę używać go do przetwarzania niektórych plików:

_.each(fileList, function(element, index, list){ 
    _.each(element, function(el, idx, lst){ 
     promisesQueue.push({funct: processFile, argmnt:[el, index + (len - fileList.length) ,len]}); 
    }); 
}); 

go wykonać i wskazywać postęp:

executePromiseQueueSync(promisesQueue).then(function(){ 
    .... 
}, function(){ 
    .... 
}).progress(function(msg, progress, name, index, status, desc){ 
     console.log('progress'); 
}); 

funkcja procesu sama wygląda tak:

function processFile(file, index, size) 
{ 
    var dfd = new jQuery.Deferred(); 
    if (file.name.match('(.*)\\.jpg')) 
     ... 
    else if 
     ... 
    else 
     $.when(processWrongFileType(file)).then(function(){ 
     dfd.notify(...); 
     dfd.resolve(); 
     }); 

    return dfd.promise(); 
} 

jak widać nie ma nic do zrobienia, gdy plik ma niewłaściwy typ:

Więc czasami chciałbym wykonać kod synchroniczny jak obietnica:

function processWrongFileType(){ 
    var dfd = new jQuery.Deferred(); 
    dfd.resolve(); 
    console.log("blah"); 
    return dfd.promise(); 
} 

The problem polega na tym, że jeśli processWrongFileType zostanie wykonany, powiadomienie nie zadziała. Jeśli zmienię processWrongFileType wyglądać tak:

function processWrongFileType() 
{ 
    var dfd = new jQuery.Deferred(); 
    setTimeout(function(){dfd.resolve();},1); 
    return dfd.promise(); 
} 

powiadomić() będzie działać. Czy istnieje sposób na uniknięcie funkcji setTimeout i nadal działa funkcja notify() ze zdarzeniem progress?

+0

można pokazać pełniejszy przykład twój $ .Przy użyciu X? –

+2

To, co robisz, powinno działać ... http://jsfiddle.net/3XD9v/ Zgaduję, że powód, dla którego nie działa, jest związany ze sposobem, w jaki łączysz powyższe fragmenty lub kod dookoła. –

+4

Dlaczego miałbyś go rozwiązać, zanim zwrócisz obietnicę? Jesteś pewien, że nie szukasz funkcji zwrotnej, ponieważ nie ma to dla mnie większego sensu? – adeneo

Odpowiedz

1

Nie musisz robić nic specjalnego, aby użyć kodu synchronizacji jako obietnicy.

Wystarczy zwracana wartość to ==true

$.when((function() { 
    return prompt('really?') 
})()).then((function() { 
    return alert('yeah') 
})()).done((function() { 
    alert('done') 
})()) 
Powiązane problemy