Transformation awaits an endless cycle into a raw promise.

As far as I know, async/awaitthis is just syntactic sugar over promise.then. Consider this piece of code:

function sleep(n){
    return new Promise(res => setTimeout(res, n));
}

function* range(n){
    var i = 0;
    while(i < n)    yield i++;
}
async function doStuff(){
    for(let n of range(10)){
        console.log(n);          // print the number
        await sleep(1000);       // wait for 1 second
    }
}

async/awaitmakes the code very linear, efficient and clear. It should be borne in mind that rangethere should not be an actual end for this.

Now the problem is how this can be rewritten using the era of ES7 to ES7 promise.then. It is possible to implement the same cycle:

function doStuff(){
    return Array.from(range(10)).reduce((acc, ele) => {
        return acc
            .then(() => console.log(ele))
            .then(() => sleep(1000))
    }, Promise.resolve());
}

Ignoring the fact that the code is not very elegant, use Array.from(range(10))

  • creates an additional array that is not needed, and
  • It is expected to range(10)end in the future.

Not like a good conversion.

, yield await, ES5. :

  • , ES5
  • sleep
  • sleep, .
  • doStuff :

    doStuff().finally(cleanUp);  // clean up if something failed
    
  • ()

?

+4
3

, , , , .

, ( setTimeout, , ).

    function sleep(n){
      return new Promise(res => setTimeout(_=>res(n/100), n));
    }

    function* range(n){
      var i = 0;
      while(i < n)    yield i++;
    }

    function doStuff(){
      const processValue = 
        resolve => {
          console.log("resolved with:",resolve);
          // if(resolve===3){throw "nope";}
          return sleep(resolve*100);
        },
      rec = (p,iter) => {
        const result = iter.next();
        if (result.done){
          return p;
        }
        p = p.then(_=>processValue(result.value))
        return p.then(
          resolve=>{
            return rec(p,iter)
          }
        );
      },
      iter = range(10),
      firstResult = iter.next();
      if(firstResult.done){
        return processValue(firstResult.value);
      }
      return rec(processValue(firstResult.value),iter);
    }

    doStuff()
    .then(
      x=>console.log("done:",x)
      ,reject=>console.warn("fail:",reject)
    );
+1

, , async. , promises, async-q. :

var n = 0;
async.whilst(() => n < 10, () => {
    n++;
    console.log(n);
    return sleep(1000);
})
+1

If I understand all your requirements correctly, this may correspond to all:

function chainPromises(max, callback) {
    return Promise.resolve(0).then(function res(num) {
        num++;
      return sleep(1000)
        .then(console.log(num))
        .then(num < max && !stopCtr ? res.bind(null, num): callback);
  });
}

Snapshot here:

var stopCtr = 0;
var running = 0;

function sleep(n){
    return new Promise(res => setTimeout(res,n));
}

function cleanUp() {
	console.log('Cleaned Up!');
  stopCtr, running = 0, 0;
}
function chainPromises(maxNum, callback) {
  if (running) {
    console.log('another action in progress');
    return;
  }
  
  running = 1;
  
	return Promise.resolve(0).then(function res(num) {
  		num++;
      return sleep(1000)
      	.then(console.log(num))
      	.then(num < maxNum && !stopCtr ? res.bind(null, num): callback);
  });
}

function chainTenPromises() {
  chainPromises(10, cleanUp);
}

function chainInfinitePromises() {
  chainPromises(Infinity, cleanUp);
}
<button type="button" id="start-ctr" onclick="chainTenPromises()">Count Ten</button>
<button type="button" id="start-ctr" onclick="chainInfinitePromises()">Count Infinite</button>
<button type="button" id="stop-ctr" onclick="stopCtr=1">Stop Counter</button>
Run code
0
source

Source: https://habr.com/ru/post/1690213/


All Articles