2017-01-23 3 views
1

КонтекстНе удается скомпилировать код асинхронной с генераторами в машинописном

  1. В моем путешествии в машинописном, мне посоветовали, что блокирующие вызовы никогда не должно быть сделано в асинхронном коде.

  2. Я также использую генераторы, так как они облегчают прохождение каталогов и избегают исчерпания пространства стека.

Однако, когда я совмещаю код асинхронного (в данном случае: readdir) с генераторами, компилятор жалуется, что выход может быть использован только внутри генераторов, что приводит меня к мысли о том, что компилятор не в состоянии объединить замыкания, генераторы и асинхронный код, все за один раз.

function *yyyymmGenerator(dir: string, props: Props) { 
    const fs = require("fs"); 
    const yyyy = props.range.getUTCFullYear().toString(); 
    const mm = props.range.getUTCMonth().toString(); 
    const start = `${yyyy}-${mm}`; 

    const files = fs.readdir(dir, function(err, files) { 
     for (let i = 0; i < files.length; i++) { 
      const file: string = files[i]; 
      if (file.localeCompare(start) >= 0) { 
       const d = `${dir}/${file}`; 
       yield file; 
      } 
     } 
    }); 
} 

error TS1163: A 'yield' expression is only allowed in a generator body. 

Вопросы

Что бы быть рекомендуемым лучшая практика в такой ситуации?

Было бы хорошо, если бы я просто рассматривал все, синхронизируя, блокируя код, но «обертывая» вызов внутри обещания?

+0

См http://stackoverflow.com/questions/41326217/js-how-to-use-generator-and- yield-in-a-callback –

ответ

1

Вы могли бы сделать что-то подобное (называют next функции внутри обратного вызова):

const gen = yyyymmGenerator(args); 

function callback(err, files) { 
    if(err) return gen.throw(err); 
    gen.next(files); 
    // Print all files returned by the generator 
    for(file of gen) { 
    console.log(file); 
    } 
} 

function *yyyymmGenerator(dir: string, props: Props) { 
    const fs = require("fs"); 
    const yyyy = props.range.getUTCFullYear().toString(); 
    const mm = props.range.getUTCMonth().toString(); 
    const start = `${yyyy}-${mm}`; 

    const files = yield fs.readdir(dir, callback); 

    for (let i = 0; i < files.length; i++) { 
     const file: string = files[i]; 
     if (file.localeCompare(start) >= 0) { 
     const d = `${dir}/${file}`; 
     yield file; 
     } 
    } 
} 

gen.next(); // Start generator 
+0

Я понимаю решение, которое вы предложили, и я думаю, что это будет работать в принципе. Однако я хотел бы понять, должен ли я (или мог?) Считать сообщение об ошибке свидетельством того, что компилятор ограничен в отношении задействованных областей. Или даже если это можно считать ошибкой в ​​компиляторе. Я хотел бы указать проблему, но сначала хотел бы понять, жалуется ли компилятор по вине или по дизайну. Есть идеи? –

+0

Компилятор жалуется, потому что вы использовали 'yield' вне' function * '(в обратном вызове), и это логично, потому что, когда вы вызываете функцию async, выполнение генератора не останавливается, в вашем примере генератор, вероятно, будет завершено до выполнения обратного вызова readdir –

 Смежные вопросы

  • Нет связанных вопросов^_^