2015-12-17 19 views
5

Şablon gerektiren bir projede çalışıyorum. Ana şablon, veri kaynağını belirten bir içe aktarma özelliğine sahiptir. Daha sonra veriler String.replaceAllMapped kullanılarak okunur ve dizeye eklenir. Aşağıdaki kod, Dosya api ile düzgün çalışır çünkü dosyayı senkronize olarak okumak için readAsStringSync yöntemine sahiptir. Şimdi bir Geleceği döndüren herhangi bir keyfi akıştan okumak istiyorum.String.replaceAllSenkronize olmayan sonuç ile eşleşti

Bu senaryoda nasıl uyumsuz/beklemede çalışırım? Ayrıca, replaceAllMapped için uyumsuz bir değiştirmeyi aradım ancak normal ifadeyle birden çok geçiş gerektirmeyen bir çözüm bulamadım.

String loadImports(String content){ 
    RegExp exp = new RegExp("import=[\"\']([^\"\']*)[\"\']>\\s*<\/"); 

    return content.replaceAllMapped(exp, (match) { 
    String filePath = match.group(1); 

    File file = new File(filePath); 
    String fileContent = file.readAsStringSync(); 

    return ">$fileContent</"; 
    }); 
} 

Örnek kullanım:

print(loadImports("<div import='myfragment.txt'></div>")) 
+0

Sana ne yapmak istediğini anlayamadım, yani hangi bölümü öyle mi Gelecek 'ile değiştirmek ister misiniz? 'ReplaceAllMapped' için çağrı içinde okuduğunuz dosya içeriği? – Tonio

+0

Böyle bir işlevin yerleşik bir sürümü yok, geri bildirim işlevinin Tonio'nunki gibi olduğu gibi uyumsuz olmasını bekleyen bir yazı yazmanız gerekiyor. – lrn

cevap

2

bu deneyin:

:

Future<String> replaceAllMappedAsync(String string, Pattern exp, Future<String> replace(Match match)) async { 
    StringBuffer replaced = new StringBuffer(); 
    int currentIndex = 0; 
    for(Match match in exp.allMatches(string)) { 
    String prefix = match.input.substring(currentIndex, match.start); 
    currentIndex = match.end; 
    replaced 
     ..write(prefix) 
     ..write(await replace(match)); 
    } 
    replaced.write(string.substring(currentIndex)); 
    return replaced.toString(); 
} 

yukarıdaki örnek kullanmak için Buraya

benim kod çok basitleştirilmiş bir örnektir
Future<String> loadImports(String content) async { 
    RegExp exp = new RegExp("import=[\"\']([^\"\']*)[\"\']>\\s*<\/"); 

    return replaceAllMappedAsync(content, exp, (match) async { 
     String filePath = match.group(1); 

     File file = new File(filePath); 
     String fileContent = await file.readAsString(); 
     return ">$fileContent</"; 
    }); 
} 

Ve böyle kullandı:

loadImports("<div import='myfragment.txt'></div>").then(print); 

veya bir async işlevinde kullanıldığı takdirde:

print(await loadImports("<div import='myfragment.txt'></div>")); 
+1

Potansiyel olarak karesel yürütme süresiyle tekrarlanan birleştirme kullanmak yerine parçaları toplamak için 'StringBuffer 'kullanılmasını öneririm. Alternatif olarak, sadece listedeki parçaları toplayın ve sonunda 'List.join' kullanın. – lrn

+0

Doğru ... dize birleştirme/enterpolasyon yerine 'StringBuffer 'işlevini kullanma cevabını düzenledi. – Tonio

+1

Çözümünüzde küçük bir yazım hatası var. Yazmadan sonra noktalı virgül olmamalıdır. Çalışan bir çözüm için teşekkür ederim. Gerçek çok iş parçacıklı gelişmeden olay döngüsüne geçiş şaşırtıcı derecede zordur. – Zig158

İlgili konular