Bug 1441527 - Adapt Task middleware to async functions. r=jryans
MozReview-Commit-ID: 99NjKtf2krk
--- a/devtools/client/shared/redux/middleware/task.js
+++ b/devtools/client/shared/redux/middleware/task.js
@@ -1,31 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Task } = require("devtools/shared/task");
-const { executeSoon, isGenerator, reportException } = require("devtools/shared/DevToolsUtils");
+const { executeSoon, isGenerator, isAsyncFunction, reportException } =
+ require("devtools/shared/DevToolsUtils");
const ERROR_TYPE = exports.ERROR_TYPE = "@@redux/middleware/task#error";
/**
* A middleware that allows generator thunks (functions) and promise
* to be dispatched. If it's a generator, it is called with `dispatch`
* and `getState`, allowing the action to create multiple actions (most likely
* asynchronously) and yield on each. If called with a promise, calls `dispatch`
* on the results.
*/
function task({ dispatch, getState }) {
return next => action => {
if (isGenerator(action)) {
return Task.spawn(action.bind(null, dispatch, getState))
.catch(handleError.bind(null, dispatch));
}
+ if (isAsyncFunction(action)) {
+ return action(dispatch, getState)
+ .catch(handleError.bind(null, dispatch));
+ }
/*
if (isPromise(action)) {
return action.then(dispatch, handleError.bind(null, dispatch));
}
*/
return next(action);
--- a/devtools/shared/ThreadSafeDevToolsUtils.js
+++ b/devtools/shared/ThreadSafeDevToolsUtils.js
@@ -238,16 +238,34 @@ exports.isGenerator = function (fn) {
let ctor = proto.constructor;
if (!ctor) {
return false;
}
return ctor.name == "GeneratorFunction";
};
/**
+ * Return true if `thing` is an async function, false otherwise.
+ */
+exports.isAsyncFunction = function (fn) {
+ if (typeof fn !== "function") {
+ return false;
+ }
+ let proto = Object.getPrototypeOf(fn);
+ if (!proto) {
+ return false;
+ }
+ let ctor = proto.constructor;
+ if (!ctor) {
+ return false;
+ }
+ return ctor.name == "AsyncFunction";
+};
+
+/**
* Return true if `thing` is a Promise or then-able, false otherwise.
*/
exports.isPromise = function (p) {
return p && typeof p.then === "function";
};
/**
* Return true if `thing` is a SavedFrame, false otherwise.