遅延

2016-12-10 19 views
6

のは、私が直列に約束のカップルを実行するには、次のコードを使用していましょう:遅延

let paramerterArr = ['a','b','c','d','e','f'] 
parameterArr.reduce(function(promise, item) { 
    return promise.then(function(result) { 
    return mySpecialFunction(item); 
    }) 
}, Promise.resolve()) 

コードは単純に約束を待ち、(約束を返す)mySpecialFunctionを呼び出します解決されてからmySpecialFunctionを再度呼び出します。したがって、関数は配列内のすべての要素に対して1回だけ正しい順序で呼び出されます。

mySpecialFunction(item)の呼び出しごとに少なくとも50ミリ秒の遅延があることを確認するにはどうすればよいですか?

約束事が正しい順序で実行され、実行時間がmySpecialFunctionのたびに変わることが重要です。

私は同期スリープがうまくいくと思いますが、別のスレッドでこのコードを実行するつもりはないので、ブラウザーで迷惑なUIがフリーズします。

setTimerを何らかの方法で使用できるかどうかはわかりません。私は約束の返還を遅らせることはできないということです。

+1

これは役に立ちます。http://bluebirdjs.com/docs/api/promise.delay.html –

+0

私はすでにそれを見ましたが、私はブルーバードを使用していません。私はネイティブプロミスを使用しています。 (ECMA6) – Forivin

答えて

8

回答は良いですが、実際の操作が50ms以上経過したかどうかに関係なく、すべての回答がに関係なくに関係なく待機しています。

Promise.allを使用できます。

const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); 
let paramerterArr = ['a','b','c','d','e','f'] 
parameterArr.reduce(function(promise, item) { 
    return promise.then(function(result) { 
    return Promise.all([delay(50), mySpecialFunction(item)]); 
    }) 
}, Promise.resolve()) 
+1

私をビートしてください37s :-) – Bergi

1

以下は、あなたが指定した期間にブロックしますが待機しない約束を達成方法の例を示します。

function timedPromise(ms, payload) { 
    return new Promise(function(resolve) { 
     setTimeout(function() { 
      resolve(payload); 
     }, ms); 
    }) 
} 


var time = Date.now(); 

timedPromise(1000) 
    .then(function() { 
     console.log(time - Date.now()); 
     return timedPromise(2000); 
    }).then(function() { 
     console.log(time - Date.now()); 
     return timedPromise(3000); 
    }); 

ので、正確に何をしたいに応じて、次のことができるようにすべきですこのような何か:周りに持っている

let paramerterArr = ['a','b','c','d','e','f'] 
parameterArr.reduce(function(promise, item) { 
    return promise.then(function(result) { 
    return mySpecialFunction(item); 
    }).then(function(specialResult) { 
    return timedPromise(50, specialResult); 
    }); 
}, Promise.resolve()) 
3

本当に便利なユーティリティ機能は、私がdelay()呼び出すものです:

function delay(t, val) { 
    return new Promise(function(resolve) { 
     if (t <= 0) { 
      resolve(val); 
     } else { 
      setTimeout(resolve.bind(null, val), t); 
     } 
    }); 
} 

その後、あなたはこのような約束チェーンでそれを使用することができます。

let paramerterArr = ['a','b','c','d','e','f'] 
parameterArr.reduce(function(promise, item, index) { 
    return promise.then(function(result) { 
    // no delay on first iteration 
    var delayT = index ? 50 : 0; 
    return delay(delayT, item).then(mySpecialFunction); 
    }) 
}, Promise.resolve()); 

ます。また、オプションの遅延で、順次繰り返しを行うための小さなユーティリティ関数を作ることができます:

// delayT is optional (defaults to 0) 
function iterateSerialAsync(array, delayT, fn) { 
    if (!fn) { 
     fn = delayT; 
     delayT = 0; 
    } 
    array.reduce(function(p, item, index) { 
     return p.then(function() { 
      // no delay on first iteration 
      if (index === 0) delayT = 0; 
      return delay(delayT, item).then(fn) 
     }); 
    }, Promise.resolve()); 
} 

そして、あなたは次のように使用します:

iterateSerialAsync(paramerterArr, 50, mySpecialFunction).then(function(finalVal) { 
    // all done here 
}); 
1

彼女あなたが行くE:https://jsbin.com/suvasox/edit?html,js,console

let paramerterArr = ['a','b','c','d','e','f'] 
paramerterArr.reduce((p, val) => { 
    return p.then(() => { 
    return new Promise((res) => { 
     setTimeout(() => { res(mySpecialFunction(val)); }, 1000); 
    }); 
    }); 
}, Promise.resolve()); 

p)は(p.thenの結果である必要があります。あなたが約束を繋ぐ方法だけです。

注目に値するのは、1000msの遅延に変更しました。

2

Promise.allを使用し、少なくとも 50msの遅延を取得するには:

function delay(t) { 
    return new Promise(function(resolve) { 
    setTimeout(resolve, t); 
    }); 
} 
parameterArr.reduce(function(promise, item) { 
    return promise.then(function() { 
    return Promise.all([ 
     mySpecialFunction(item), 
     delay(50) 
    ]); 
    }); 
}, Promise.resolve()); 
0

これは私がそれを実装したいmySpecialFunctionの要件であると考えられるからです。機能の遅れ自体だからそれは、最後のコール

const delayBetweenCalls = (delay, fn) => { 
    let lastCall = NaN; 
    return function(/*...arguments*/){ 
     //this and arguments are both forwarded to fn 

     return new Promise(resolve => { 
      let poll =() => { 
       let delta = Date.now() - lastCall; 
       if(delta < delay){ 
        setTimeout(poll, delta - delay); 
       }else{ 
        lastCall = Date.now(); 
        resolve(fn.apply(this, arguments)); 
       } 
      } 
      poll(); 
     }) 
    } 
} 

後未満は50msで呼び出された場合:

const mySpecialFunction = delayBetweenCalls(50, function(some, ...args){ 
    return someValueOrPromise; 
}); 

//and your loop stays the same: 
parameterArr.reduce(function(promise, item) { 
    return promise.then(function(result) { 
     return mySpecialFunction(item); 
    }) 
}, Promise.resolve()) 

ので、/どのようにmySpecialFunctionが呼び出される場合、常に存在します重要ではありません。渡されたコールバックの中でコードを実行する前に、少なくとも50msの遅延が必要です。