livewires / you-win

a friendly games library for young people who've probably used Scratch before
https://livewires.github.io/you-win/install
8 stars 1 forks source link

Promises #9

Open tjvr opened 7 years ago

tjvr commented 7 years ago

Proposal: forever and Sound.play should return a Promise. That way, you can do stuff after they finish.

Example for forever:

forever(() => {
  player.x += 1
  if (player.left > world.width) {
    return false // stop forever
  }
}).then(() => {
  player.y += 1
  // ...
})

sound.play().then(() => { … }) would act like "play sound and wait" from Scratch.

My concern is that introducing Promises really complicates the concept of control flow—because they're a poor fit for the nature of JavaScript! Using await/async might help alleviate this, but then we're introducing more confusing keywords.

Help!

bates64 commented 7 years ago

I'd argue that async/await is less confusing - especially if you don't know that they're actually promises. If everything is async/await it simplifies a lot of code.

await UW.init(...)
let player = (...)

await waitSeconds(5) // etc
tjvr commented 7 years ago

Interesting thought. Can await/async be used at the top-level scope in an ES module?

bates64 commented 7 years ago

No.

You'd have to do:

import 'you-win' as UW

async function main() {
  await UW.init()
  // ...
}

main().catch(console.error)

Which I'd argue is fairly ugly. You could do:

import 'you-win' as UW

UW.init(...).then(async () => {
  // ...await foo()
}).catch(console.error) // not sure if you need this in browsers?

Which is almost the same as the current recommended way of initialising, except it has an async keyword.

bates64 commented 7 years ago

Or, if the game itself could be considered a module (this allows us to easily have an actual restart() method, too!)

import 'you-win' as UW

export async function main() {
  await UW.init()
  // ...
}

And then we somehow dynamically import that script (babel in the browser??) and execute main(). Perhaps you could run it in a Web Worker - and kill the web worker upon restart()!

tjvr commented 7 years ago

No.

Aw. :(

An export is an interesting idea, though I don't think it's required in order to have a restart() method...