I Promise, this shall NOT be painless

by Admiral Potato

HTML

<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app">
	<pre>
		<div
			v-for="item in output"
			:class="{
				error: item.error
			}"
		>{{item.text || item.error}}</div>
	</pre>
	<div>
		<label
			:class="{
				error: shouldError
			}"
		>
			<span>should error?</span>
			<input
				type="checkbox"
				v-model="shouldError"
			/>
		</label>
	</div>
	<button
		@click="usePromiseWithThen"
	>usePromiseWithThen</button>
	<button
		@click="usePromiseWithAwait"
	>usePromiseWithAwait</button>
</div>

CSS

* {
	margin: 0;
	padding: 0;
	font-family: inherit;
	line-height: 1.5em;
}
html, body {
	height: 100%;
	font-size: 16px;
	font-family: monospace;
}
body {
	background-color: #000;
	color: #aaa;
	padding: 2em;
}
.error {
	color: #f66;
}

JavaScript

var makeTimerPromise = (
	delaySeconds,
	shouldFail = false
) => {
	var howToSetUpThePromise = (resolve, reject) => {
		var functionToRunAfterDelay = () => {
			if (shouldFail) {
				reject(`I waited ${delaySeconds} to reject`)
			} else {
				resolve(`I waited ${delaySeconds} to resolve`)		
			}
		}
		setTimeout(
			functionToRunAfterDelay,
			delaySeconds * 1000
		)
	}
	return new Promise(howToSetUpThePromise)
}

var app = new Vue({
	el: '#app',
	data: {
		shouldError: false,
		output: [
			{error: 'error output with left beef'},
			{text: 'none output with left beef'},
		]
	},
	methods: {
		usePromiseWithThen () {
			var delay = 2 + (Math.random() * 3)
			this.output.push({
				text: `usePromiseWithThen - Delay: ${delay}`
			})
			var timerPromise = makeTimerPromise(
				delay,
				this.shouldError,
			)

			timerPromise
				.then((successMessage) => {
					this.output.push({
						text: successMessage
					})
				})
				.catch((error) => {
					this.output.push({
						error: error
					})
				})
		},
		async usePromiseWithAwait () {
			var delay = 2 + (Math.random() * 3)
			this.output.push({
				text: `usePromiseWithAwait - Delay: ${delay}`
			})
			try {
				var timerResult = await makeTimerPromise(
					delay,
					this.shouldError,
				)
				this.output.push({
					text: timerResult
				})
			} catch (error) {
				this.output.push({
					error: error
				})			
			}
		},
	}
})