How can I guarantee the resolution order of several promises?

An attempt to learn some modern JS and, in particular, ECMAScript 6 Promises. I play with this simple test:

let slow = new Promise((resolve) => {
  setTimeout(function()
  {  
	console.log('slow');
	resolve();	
  }, 2000, 'slow');
});

let instant = new Promise((resolve) => {
	console.log('instant');
	resolve();	
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
	console.log('quick');
	resolve();	
  }, 1000, 'quick');
});

Promise.all([slow, instant, quick]).then(function(results) {
  console.log('finished');
}, function(error) {
  console.log(error);	
});
Run codeHide result

I want here to start all asynchronous Promises events at the same time. And write down when it's all over. In the console, this is displayed as expected: “instant”, “fast”, “slow” and “finished”.

However, what if I wanted to be sure that "instant" does not perform an echo / log before "slow" is completed? That is, I want the console to record “fast”, “slow”, “instant” and “completed” ... but at the same time, they should still be run simultaneously with the asynchronous one.

How can i achieve this?

+4
6

, , , promises , ?

:

let slow = new Promise((resolve) => {
  setTimeout(function()
  {
    // Rather than log here, we resolve to the value we want to log
    resolve('slow');
  }, 2000, 'slow');
});

let instant = new Promise((resolve) => {
    resolve('instant');  
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
    resolve('quick');  
  }, 1000, 'quick');
});

// All Promises are now running. Let print the results...

// First wait for the result of `slow`...
slow.then((result) => {
  // Result received...
  console.log(result);
  
  // Now wait for the result of instant...
  instant.then((result) => {
    
    // Result received...
    console.log(result);
    
    // Now wait for the result of quick...
    quick.then((result) => {
      
      // Result received...
      console.log(result);
      
    }).then((result) => {
      // Done
      console.log('finished');
    });
  });
});
Hide result

, cchamberlain answer , promises . , . ( , quick 2500 , 500 instant.) .

, , , async/await ES2017 :

let slow = new Promise((resolve) => {
  setTimeout(function()
  {
    // Rather than log here, we resolve to the value we want to log
    resolve('slow');
  }, 2000, 'slow');
});

let instant = new Promise((resolve) => {
    resolve('instant');  
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
    resolve('quick');  
  }, 1000, 'quick');
});

// All Promises are now running. Let print the results...

async function logResults(...promises) {
  for (let promise of promises) {
    console.log(await promise);
  }
}

logResults(slow, instant, quick).then(() => console.log('finished'));
Hide result

Babel. : Babel ( 2016 ). .

+2

, , , . - :

let slow = new Promise((resolve) => {
  setTimeout(() => resolve('slow'), 2000)
})

let instant = new Promise((resolve) => {
  // In the future setImmediate can be used here to ensure async execution. For now, setTimeout with 0MS effectively does the same thing.
  setTimeout(() => resolve('instant'), 0)
})

let quick = new Promise((resolve) => {
  setTimeout(() => resolve('quick'), 1000)
})

Promise.all([slow, instant, quick]).then(function(results) {
  for(let result of results) {
    console.log(result)
  }
  console.log('finished')
}, function(err) {
  console.error(err)
})
Hide result

, .

+2

, setTimeout, .

const slow = new Promise((resolve) => {
  setTimeout(() => {
    console.log('slow - from setTimeout');
    resolve('slow - from resolve');
  }, 2000, 'slow');
});

const instant = new Promise((resolve) => {
  console.log('instant - from setTimeout');
  resolve('instant - from resolve');
});

const quick = new Promise((resolve) => {
  setTimeout(() => {
    console.log('quick - from setTimeout');
    resolve('quick -from resolve');
  }, 1000, 'quick');
});

Promise.all([slow, instant, quick]).then((results) => {
  console.log(results);
  console.log('finished');
}, (error) => {
  console.log(error);
});
Hide result

resolve Promise.all. , , .

+2

"" / ""

.

, Promise.all(), .then() Promise.all() console.log() .

" ?"

" promises?"

. .


Promise.all promises , . , , promises . -, , , Promise.resolve.

let slow = new Promise((resolve) => {
  setTimeout(function(value) {  
	resolve(value);	
  }, 2000, "slow");
});

let instant = new Promise((resolve) => {
	resolve("instant");	
});

let quick = new Promise((resolve) => {
  setTimeout(function(value) {  
	resolve(value);	
  }, 1000, "quick");
});

Promise.all([slow, instant, quick]).then(function(results) {
  console.log("finished");
  console.log(results.join("\n"))
}, function(error) {
  console.log(error);	
});
Hide result
0

Promise.all() .

Promise, , console.log() resolve() reject(). . .then() Promise, , .then() . Promise .then() .

let results = [];

let pace = value => {console.log(value); results.push(value); return results};

let slow = () => new Promise((resolve) => {
  setTimeout((value) => {  
    resolve(value);  
  }, 2000, "slow");
});

let instant = () => new Promise((resolve) => {
    resolve("instant");  
});

let quick = () => new Promise((resolve) => {
  setTimeout((value) => {  
    resolve(value);  
  }, 1000, "quick");
});

slow().then(pace)
.then(instant).then(pace)
.then(quick).then(pace)
.then(res => console.log("finished, results:", res))
.catch(error => console.log(error));
Hide result
-1

, 3 promises . "". , , promises , .

let slow = new Promise((resolve) => {
  setTimeout(function()
  {  
    resolve();
  }, 2000);
});

let instant = new Promise((resolve) => {
    resolve();
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
    resolve();
  }, 1000);
});

instant.then(function(results) {
  console.log("instant");
}).then(function(){return quick;}).then(function(results) {
  console.log("quick");
}).then(function(){return slow;}).then(function(results) {
  console.log("slow");
}).then(function(){ return Promise.all([slow, instant, quick]);}).then(function(results) {
  console.log('finished');
}).catch(function(error) {
  console.log(error);   
});
Hide result

This ensures that you will handle permissions in order.

Note. . In your example, you are using setTimeout, which is guaranteed to be called by handlers in order of time, so your existing code will already write "instant", "fast", "slow", "finished". The code I provided guarantees this order for any set of promises with different resolution times.

-1
source

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


All Articles