Home > Net >  Promise.allSettled where promises list is varied incrementally
Promise.allSettled where promises list is varied incrementally

Time:05-12

Result: a, b, d, c. Expected: a, b, c, d

 const promises = []
    console.log('a')
    someFunc(promises)
    Promise.allSettled(promises).then(() => console.log('d'))

    function someFunc(promises) {
      const promise = new Promise(resolve => setTimeout(() => {
        console.log('b')
        const promise2 = new Promise(resolve2 => setTimeout(() => {
          console.log('c')
          resolve2()
        }, 3000))
        promises.push(promise2)
        resolve()
      }, 3000))
      promises.push(promise)
      return promise
    }

CodePudding user response:

While it'd be possible to patch it up by not pushing to an array, but instead having each Promise chain off of each other in someFunc...

console.log('a')
someFunc().then(() => console.log('d'))

function someFunc() {
  return new Promise(resolve => setTimeout(() => {
    console.log('b')
    new Promise(resolve2 => setTimeout(() => {
      console.log('c')
      resolve2()
    }, 3000))
      .then(resolve);
  }, 3000))
}

A much more understandable version would promisify setTimeout to begin with instead of doing it every time.

const setTimeoutPromise = ms => new Promise(resolve => setTimeout(resolve, ms));

console.log('a')
someFunc().then(() => console.log('d'))

function someFunc() {
  return setTimeoutPromise(3000)
    .then(() => {
      console.log('b');
      return setTimeoutPromise(3000)
    })
    .then(() => {
      console.log('c');
      return setTimeoutPromise(3000)
    });
}

Which can be further simplified with await...

const setTimeoutPromise = ms => new Promise(resolve => setTimeout(resolve, ms));

console.log('a')
someFunc().then(() => console.log('d'))

async function someFunc() {
  await setTimeoutPromise(3000);
  console.log('b');
  await setTimeoutPromise(3000);
  console.log('c');
  await setTimeoutPromise(3000);
}

CodePudding user response:

Solution

I know you may be confused on this question a lot. Here is the solution I found

const promises = []
const timeout = ms => {
    const promise = new Promise(resolve => setTimeout(resolve, ms))
    promises.push(promise)
    return promise
}

const someFunc = () =>
    timeout(1000).then(() => {
        console.log('b')
        timeout(1000).then(() => console.log('c'))
    })

async function main() {
    console.log('a')
    someFunc()
    let i = 0;
    while (promises.length > i) {
        i = promises.length
        await Promise.allSettled(promises)
    }
    console.log('d')
}

main()

The problem I really want to express is that the content of the function someFunc is not determined at compile time while I need to make sure that the function leave no side effect once executed.

  • Related