diff --git a/package.json b/package.json
index e55a497e1..2d4d54773 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,8 @@
   },
   "dependencies": {
     "htmlparser2": "3.9.0",
-    "memoizee": "0.3.10"
+    "memoizee": "0.3.10",
+    "promise": "7.1.1"
   },
   "devDependencies": {
     "eslint": "2.7.0",
diff --git a/src/blocks/scratch3_operators.js b/src/blocks/scratch3_operators.js
index 837411262..4237f47da 100644
--- a/src/blocks/scratch3_operators.js
+++ b/src/blocks/scratch3_operators.js
@@ -1,3 +1,5 @@
+var Promise = require('promise');
+
 function Scratch3OperatorsBlocks(runtime) {
     /**
      * The runtime instantiating this block package.
@@ -81,10 +83,13 @@ Scratch3OperatorsBlocks.prototype.random = function (args, util) {
     // @todo Match Scratch 2.0 implementation with int-truncation.
     // See: http://bit.ly/1Qc0GzC
     util.yieldAndBlock();
-    setTimeout(function() {
-        var randomValue = (Math.random() * (args.TO - args.FROM)) + args.FROM;
-        util.report(randomValue);
-    }, 1000);
+    var examplePromise = new Promise(function(resolve) {
+        setTimeout(function() {
+            var res = (Math.random() * (args.TO - args.FROM)) + args.FROM;
+            resolve(res);
+        }, 1000);
+    });
+    return examplePromise;
 };
 
 module.exports = Scratch3OperatorsBlocks;
diff --git a/src/engine/execute.js b/src/engine/execute.js
index 008305182..e491cf778 100644
--- a/src/engine/execute.js
+++ b/src/engine/execute.js
@@ -1,3 +1,4 @@
+var Promise = require('promise');
 var Thread = require('./thread');
 
 /**
@@ -78,21 +79,29 @@ var execute = function (sequencer, thread) {
         done: function() {
             sequencer.proceedThread(thread);
         },
-        report: function(reportedValue) {
-            if (DEBUG_BLOCK_CALLS) {
-                console.log('Reported: ', reportedValue);
-                console.timeEnd('Yielding reporter evaluation');
-            }
-            thread.pushReportedValue(reportedValue);
-            sequencer.proceedThread(thread);
-        },
         timeout: thread.addTimeout.bind(thread),
         stackFrame: currentStackFrame.executionContext,
         startSubstack: function (substackNum) {
             sequencer.stepToSubstack(thread, substackNum);
         }
     });
-    if (thread.status === Thread.STATUS_RUNNING) {
+
+    // Deal with any reported value.
+    // If it's a promise, wait until promise resolves.
+    var isPromise = (
+        primitiveReportedValue &&
+        primitiveReportedValue.then &&
+        typeof primitiveReportedValue.then === 'function'
+    );
+    if (isPromise) {
+        primitiveReportedValue.then(function(resolvedValue) {
+            if (DEBUG_BLOCK_CALLS) {
+                console.log('reporting value: ', resolvedValue);
+            }
+            thread.pushReportedValue(resolvedValue);
+            sequencer.proceedThread(thread);
+        });
+    } else if (thread.status === Thread.STATUS_RUNNING) {
         if (DEBUG_BLOCK_CALLS) {
             console.log('reporting value: ', primitiveReportedValue);
         }