2016-10-05 2 views
2

У меня есть эта функция:Перейдите к следующему шагу только тогда, когда функция была запущена в 10 раз

function setIntervalX(callback, delay, repetitions): Promise<any> { 

    let promises = []; 

    var x = 0; 
    var intervalID = window.setInterval(function() { 
    callback(); 
    if (++x === repetitions) { 
     window.clearInterval(intervalID); 
     promises.push(new Promise((resolve, reject) => {}); 
    } 
    }, delay); 
    return Promise.all(promises); 
} 

Моя цель заключается в вызове функции в тесте и кормовой эти 10 вызовов закончились, я хочу позвонить ожидать в моей функции. Так это значит, что я должен ждать его до конца, как это:

setIntervalX(() => { 

    //logic here 

    }, 1000, 10).then(() => { 
        expect(something).toBe(anotherThing); 
        }); 

Я чувствую, что мой способ сделать это некрасиво, и может быть сделано Bettery. Какие-либо предложения?

+0

Хорошо, я отформатировал его, вы поможете сейчас :)? –

+0

С уважением, но посмотрите на выше. Вы действительно называете это «последовательно и читаемо» отформатированным? 'callback' смещается в первом блоке кода, что вводит в заблуждение; этот первый блок также по-прежнему содержит несогласованные отступы другими способами; и чем меньше говорят о втором блоке кода, тем лучше. Изменив свой пост и код и продемонстрировав, что вы нашли время для этого, улучшите свои шансы получить хорошие ответы. –

+0

Если это тест, почему вы проводите интервалы с интервалом в 1 секунду вместо того, чтобы просто запускать их назад? Из вашего вопроса также неясно, может ли «обратный вызов» вернуть обещание, т. Е. Эффективно представляет асинхронную операцию, и требуется ли меньше секунды для выполнения (что означает, что тесты выполняются последовательно) или более (они в конечном итоге выполняются одновременно т.е. параллельно). Уточнение этого может сделать его более правильным. – jib

ответ

2

Если вы не нужны индивидуальные обещания (вы никогда не использовать их выше, за исключением Promise.all), просто использовать одно обещание:

function setIntervalX(callback, delay, repetitions): Promise<any> { 
    return new Promise(resolve => { 
     let x = 0; 
     let intervalID = window.setInterval(function() { 
      callback(); 
      if (++x === repetitions) { 
       window.clearInterval(intervalID); 
       resolve(); 
      } 
     }, delay); 
    }); 
} 
+0

отлично, но он все еще не изящный и может быть сделан лучше? –

+0

@JerzyGruszka: Помимо удаления ненужного «окна» на функциях таймера, я не уверен, что еще вы бы сделали. –

+0

@ T.J.Crowder это не позволяет правильно распространять ошибки, если callback() выдает или возвращает отклоненное обещание. – jib

1

Вы помечена RxJS, а так я брошу из раствора Rx.

function setIntervalX(callback, delay, repetitions): Observable<any> { 
    //Emit an event every delay 
    return Rx.Observable.interval(delay) 
    //Only accept a certain number of events 
    .take(repetitions) 
    // Process the callback each time 
    .do(() => callback()) 
    // Convert the result into a promise 
    .toPromise(); 
} 

setIntervalX(() => { 
    //logic here 
}, 1000, 10) 
.then(() => {     
    expect(something).toBe(anotherThing); 
}); 
1

Вы хотите более элегантное решение, как это:

var wait = ms => new Promise(resolve => setTimeout(resolve, ms)); 
 

 
let setIntervalX = (cb, delay, reps) => 
 
    Promise.all(Array(reps).fill().map((n, i) => wait(delay * (i + 1)).then(cb))); 
 

 
// Demo: 
 

 
let test =() => Promise.resolve().then(() => (console.log("test"), "!")); 
 

 
setIntervalX(test, 1000, 10).then(results => console.log(results.join("")));

интерпретировать код в вашем вопросе, как желание поддержать обещание возвращающих callback с. Это поддерживает это, а также правильно распространяет ошибки, что трудно сделать с setInterval.

API-интерфейсы и setTimeout имеют ужасные характеристики обработки ошибок и могут быть плотно сжаты в крошечных обещаниях, возвращающих функции, которые никогда не будут вызваны напрямую.

Обратите внимание, что при высоких значениях repetitions это не особенно эффективно.

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