2016-03-30 23 views
1

Kodumda uzun zamandır beni şaşırmış bir hataya rastladım ve bazı açıklamaları arıyorum. Bu kodda Anlamak .then() ES6

, dışarı yorumladı iç vaadi bir soruna neden oldu. Sonunda Promise.all(), setTimeout isabeti en kısa sürede, zaman aşımı içindeki çözümden sonra değil, devam ediyordu.

vaadi ile zaman uyumsuz kod akış problemi giderir tamamlayan, ama neden burası?

Esasen, neden sadece .sonra içinde() zinciri, zaman uyumsuz geri arama sonunda bir dönüşü bir Promise.resolve() Normal zaman uyumsuz kodunu koşamam? çalışan koda

var asyncPromise = function() { 
    return new Promise(function(resolve, reject) { 
     setTimeout(function() { 
      console.log('Async Promise done'); 
      resolve(); 
     }, 1000); 
    }); 
}; 

var generateSignupPromises = function(qty) { 
    var promiseArray = []; 
    for (var i = 1; i <= qty; i++) { 
     promiseArray.push(
      function() { 
       return asyncPromise() 
       .then(function() { 
        console.log('Before Timeout'); 

        //Uncommenting this fixes the issue 
        //return new Promise(function(resolve, reject) { 
         setTimeout(function() { 
          console.log('After Timeout'); 
          //resolve(); 
          return Promise.resolve(); 
         }, 500); 
        //}) 
       }); 
      } 
     ); 
    } 
    return promiseArray; 
}; 

var test = generateSignupPromises(1); 

Promise.all([test[0]()]) 
.then(function() { 
    console.log('Done'); 
}); 

Bağlantı: http://www.es6fiddle.net/imfdtuxc/

+4

Ne yapmak çalıştığınız şeyi söyleyemem: Bir geri arama gelen bir söz dönebilir ve bu nihai sonuca başka söz almak istiyorsanız

, bir then geri arama olmalıdır ancak setTimeout() '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' \ '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' hiçbir şey iade edilen değere dikkat etmeyecektir. – Pointy

+2

Doom Piramidi + anonim işlevlerin bolluğu = okunamayan kod + beklenmedik davranış. – Amit

+1

setTimeout eşzamansız değil. Eşzamanlı olarak döndürülür ve sonra() 'ın' vaat 'olan tanımsız sona dönmesine neden olur. Ekstra satırınızı ekleyerek, "çözüme" kadar bekleyecek başka bir söz verir. BTW. Bu sözlerin nasıl kullanılması gerektiği değildir. – Wainage

cevap

4

neden sadece .sonra içinde() zinciri, zaman uyumsuz geri arama sonunda bir dönüşü bir Promise.resolve() Normal zaman uyumsuz kodunu koşamam?

Gayet can

. Ama herhangi bir değer - o bir söz ya da her ne olursa olsun - return bir düz zaman uyumsuz geri arama sadece her zamanki gibi yok sayılır. ve then bunun için beklemek olabilir şey asenkron olay hakkında bilemezsiniz - bu konuda bir then geri arama değişiklikleri içine asenkron işlem başlatılırken, setTimeout sadece bir söz dönmez şey yoktur

.

asyncPromise() 
.then(function() { 
    return new Promise(function(resolve, reject) { 
// ^^^^^^ 
     setTimeout(resolve, 500); 
    }).then(function() { 
//  ^^^^^^^^^^^^^^^ 
     return Promise.resolve(); 
    }); 
}); 
0

Sonra içeride o zaman uyumsuz görev yapmak istiyorsanız, bir Promise dönmek zorunda böylece bir senkronizasyon fonksiyonudur. Ayrıca, Promise.all bir dizi söz beklemektedir. Bir dizi dizisi değil.

var asyncPromise = function() { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     console.log('Async Promise done'); 
     resolve(); 
    }, 1000); 
    }); 
}; 

var generateSignupPromises = function(qty) { 
    var promiseArray = []; 
    for (var i = 1; i <= qty; i++) { 
    promiseArray.push(
     function() { 
     return asyncPromise() 
     .then(function() { 
      console.log('Before Timeout'); 

      //Uncommenting this fixes the issue 
      return new Promise(function(resolve, reject) { 
      setTimeout(function() { 
      console.log('After Timeout'); 
      resolve(); 
      //return Promise.resolve(); 
      }, 500); 
      }) 
     }); 
     } 
    ); 
    } 
    return promiseArray; 
}; 

var test = generateSignupPromises(1); 

Promise.all([test[0]()]) 
.then(function() { 
    console.log('Done'); 
}); 

http://www.es6fiddle.net/imfe2sze/