How to write async/await or yeild code with Promise?

I have the example code using async/await in typescript

async function start() {
  for (let i = 0; i < 10; i++) {
    if (i >= 5) {
      break;
    }
    await sleep(10);
  }
}

The code is compiled blow in es6:

function start() {
  return __awaiter(this, void 0, void 0, function* () {
    if (i >= 5) {
      break;
    }
    yield (0, sleep_1.sleep)(10);
  })
}    

Now, i want to rewrite this code in rescript, but i don’t know how to do this, can anyone help me?

The current method to solve this problem in rescript for me is blow, just too complex :

let promise = ref(Promise.resolve(true))
for i in 0 to 9 {
  promise.contents = promise.contents->Promise.then(status => {
    let p = if (status) {
      sleep(10)
    } else {
      Promise.resolve()
    }
    p->Promise.then(_ => {
      if (i >= 5) {
        // simulate break, this is the only way to handle dynamic break condition for me right now
        Promise.resolve(false)
      } else {
        Promise.resolve(true)
      }
    })
  })
}

Personally I would do this in a more functional style, by sequentially resolving promises with a reducer:

let start = () =>
  Belt.Array.make(10, ())
  ->Belt.Array.reduceWithIndex(Js.Promise.resolve(), (promise, _next, index) => {
    if index >= 5 {
      Js.Promise.resolve()
    } else {
      promise |> Js.Promise.then_(_ => sleep(10))
    }
  })
  ->ignore
5 Likes

Thanks, this is better than mine. :grinning:

This can also be achieved using recursion:

let start = () => {
  let rec loop = i => {
    switch i {
    | _ if i >= 5 => Js.Promise.resolve()
    | _ => sleep(10)->Js.Promise.then_(_ => loop(i + 1), _)
    }
  }

  loop(0)
}
10 Likes

Just to throw my hat in the ring, here’s an implementation without reduce or recursion, all three solutions have pros and cons. I would probably opt for either this or the recursive method.

let start = () => {
  let promise = ref(Promise.resolve())

  for _ in 1 to 5 {
    promise.contents =
      promise.contents->Promise.then(_ => sleep(500)->Promise.thenResolve(_ => Js.log("yo")))
  }

  promise
}

Problem is that the condition i >= 5 is dynamic and will change until the promise is resolved.

Just for my clarity…whats the use of this function?

It is just a example for doing somthing frame by frame with a delay and can be interrupted dynamically until things is done.