2014-04-14 30 views
15

İçinde Promises'le uğraştım, ama onlara yeniyim ve bunu nasıl yapacağımı anlayamıyorum. Şu anda, Promise'nin bir anlamı yok çünkü async $.get tamamlanana kadar beklemiyor.Bunu async foreach döngüsünü sözlerle nasıl çalıştırırım?

Temelde, her foreach yineleme kendi $.get işlevi vardır ve ben hepsini eksiksiz ve daha sonra console.log "... albumart alır" vardır kısmına devam etmek gerekir. hat vaat ile ;

sona erdiğinde uyumlu kod

$.get(id,function(data) { 
    //(there's some code here) 
    var getZippyUrls = new Promise(function(resolve) { 
      zippyarray.forEach(function(zippy) { 
      //(more code) 
      $.get(zippy.full, function(data) { 
       //^This is the foreach of $.gets 
       //(code's here) 
      }); 
      resolve(zippyarray); 
     }); 
    }); 

    //This is my failed Promise -> 
    getZippyUrls.then(function(response) { 
     console.log("WE'RE OUT " + response.length); 
     response.foreach(function(d) { 
      console.log("Promise"+d.media); 
     }); 
     console.log('eyyyyyy'); 
    }); 

    console.log("...gets albumart"); 
    //Now after the previous stuff is done, move on 
+0

bile sorunuzu okumaya gerek yoktur. –

+1

Kodun annesi! – Arthur

+0

Her şeyi okumak zorunda değilsiniz, temel soru aynıdır - $ .get işlevlerine sahip bir foreach döngüsü var ve hepsine devam etmeden önce tamamlamaları gerekiyor. Kodu kısaltırım, sanırım ... – Fabis

cevap

20

, devamı gerçekleştirilir, devamı .then ile gerçekleştirilir. Bir söz kurucu kullandınız ve hemen çözdünüz, hiç bir görev için beklemediniz. İşlerimi görevlerimle eşleştirip sonra zincirlemeyi zincirlemek isterdim. seri,

var p = tasks[0](); // start the first one 
for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]); 
p.then(function(result){ 
     // all available here 
}); 

Ya da daha:

//I'm assuming 
zippyarray; // array of Zippy objects 

var tasks = zippyarray.map(function(zippy,i){ 
    return function(){ // return a task on that zippy; 
     // basic logic here 
     return $.get({ 
      // ajax request 
     }).then(function(data){ 
      // process data like in your code 
      // possibly store later for later use too 
      return process(data); // return the processed data; 
     }); 
    } 
}); 

Şimdi onlara tüm sıralı yürütebileceği

$.when.apply(tasks.forEach(function(t){ return t(); })).then(function(results){ 
    // all done 
}) 
+0

Neden map() fonksiyonunda 3 tane geri dönüş var anlamıyorum. Bunu benim için açabilir misin? Her biri ne yapıyor? – Fabis

+0

@Fabis dış dönüş görevi döndürür. Her bir zippiyi bir işlevle eşleştiriyoruz. İkinci dönüş görev işlevinden ve '$ .get' (bir söz) sonucunu döndürür. Üçüncü dönüş, '.then 'işleyicisinden bir değer döndürmek içindir. Genel olarak, o zaman bir işleyiciden bir değer döndürdüğünüzde, bu değeri o sözle çözecektir, eğer bu değer bir sözün kendisi ise, dış vaatlerini çözümsüz değeriyle çözecektir. –

+0

"İade işlemi()" yöntemini kullanmış olsaydım, şu hatayı alıyorum: "İşlenmemiş reddetme TypeError: Nesnenin özellik" işlemi "bir işlev değil." Döndürme işlemi sırasında işlem işlevini kullanmamam gerektiğini düşünüyorum. " –

0

bu şekilde kullanan çoklu get-İsteklerin izlemek için:

var cnt = requestCnt; 

function finished(){ 
    if(--cnt)return; 
    // Your code here 
} 

for(var i = 0; i < requestCnt; ++i){ 
    $.get('something.htm', {data:data}, function(data){ 
     finished(); 
    }); 
} 

Her zaman finişhe Bir istek bir cevap aldığında d-fonksiyonu. Tamamlandığında işlev tamamlandığında işi yapar.

+1

Bu, vaatlerle var olan mantığı elle uygular. Asenkronize semafor btw denir. –

+0

Adı bilmek güzel. Fonksiyonun arkasındaki kodu bilmek asla yanlış olmaz. Özellikle jquery-lib'inizi sayfanızda sıkıştırıyorsanız – Fuzzyma

+0

jQuery kitaplığına ihtiyacınız yoktur, modern bir tarayıcı (yeni ES6 belirtiminin bir parçası olan sözler) veya iyi bir kitaplık kütüphanesi (Bluebird gibi) kullanabilirsiniz. . Bunu kodunuz gibi elle yapmak zorunda kalmak birçok şeyi göz ardı eder (hata işleme, vb.). $ .when.apply (requests.map (function (el) {return $ .get ("something.html", {data: el});})) ve sonra (function (results) {) olarak yazılabilir./* sonuçların hepsi burada mevcut * /}); ' –

10

Bunun eski bir soru olduğunu biliyorum, ancak işler son zamanlarda biraz değişti.

Dış kütüphaneleri kullanmakta zorlanıyorsanız, Bluebird söz kitaplığı bunun için oldukça iyi bir uygulamaya sahiptir: Promise.each.

E.g.

function helperFunc(zippyarray) { 
    return Promise.each(zippyarray, zippy => { 
    return someOperationThatReturnAPromise(zippy) 
     .then((singleResult) => { 
     // do something with the operation result if needed 
     }) 
    }).then((originalArray) => { 
    // this happens only after the whole array is processed 
    // (result is the original array here) 
    return Promise.resolve(originalArray) 
    }) 
} 
+0

Merhaba, bluebird kullanmadan başka bir örnek verebilir misiniz? Sadece Promise.each'e ihtiyacım var. Bluebird kullanarak büyük bir derlenmiş dosyam var. İyi değil –

+0

Kütüphaneleri kullanmak istemiyorsanız (muhtemelen sorunun kendisinde kullanılan jQuery dışında), Bence Benjamin'in cevabı gitmek için bir yol olabilir. Veya ES6 kullanıyorsanız, istediğiniz tüm işlev çağrılarını bir koleksiyona ekleyebilir ve ardından 'Promise.all' kullanabilirsiniz. – MJV

0

Bugün sırayla yapmak gerekirse - Ben async/await ile yapacağını: o kadar kod insanlarla Tipik

//I'm assuming I'm inside an `async` function 
zippyarray; // array of Zippy objects 

for(const task of zippyArray) { 
    const result = await $.get({ ... }); 
    // do stuff with result 
} 
İlgili konular