Replace bluebird specific promise things. Fix uses of sync promise code.
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
5c24547ef5
commit
54dcaf1302
6 changed files with 53 additions and 38 deletions
|
@ -21,6 +21,7 @@ import MultiInviter from './utils/MultiInviter';
|
|||
import { _t } from './languageHandler';
|
||||
import MatrixClientPeg from './MatrixClientPeg';
|
||||
import GroupStore from './stores/GroupStore';
|
||||
import {allSettled} from "./utils/promise";
|
||||
|
||||
export function showGroupInviteDialog(groupId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -118,7 +119,7 @@ function _onGroupInviteFinished(groupId, addrs) {
|
|||
function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
||||
const matrixClient = MatrixClientPeg.get();
|
||||
const errorList = [];
|
||||
return Promise.all(addrs.map((addr) => {
|
||||
return allSettled(addrs.map((addr) => {
|
||||
return GroupStore
|
||||
.addRoomToGroup(groupId, addr.address, addRoomsPublicly)
|
||||
.catch(() => { errorList.push(addr.address); })
|
||||
|
@ -138,7 +139,7 @@ function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
|||
groups.push(groupId);
|
||||
return MatrixClientPeg.get().sendStateEvent(roomId, 'm.room.related_groups', {groups}, '');
|
||||
}
|
||||
}).reflect();
|
||||
});
|
||||
})).then(() => {
|
||||
if (errorList.length === 0) {
|
||||
return;
|
||||
|
|
|
@ -27,6 +27,7 @@ import UserProvider from './UserProvider';
|
|||
import EmojiProvider from './EmojiProvider';
|
||||
import NotifProvider from './NotifProvider';
|
||||
import Promise from 'bluebird';
|
||||
import {timeout} from "../utils/promise";
|
||||
|
||||
export type SelectionRange = {
|
||||
beginning: boolean, // whether the selection is in the first block of the editor or not
|
||||
|
@ -77,23 +78,16 @@ export default class Autocompleter {
|
|||
while the user is interacting with the list, which makes it difficult
|
||||
to predict whether an action will actually do what is intended
|
||||
*/
|
||||
const completionsList = await Promise.all(
|
||||
// Array of inspections of promises that might timeout. Instead of allowing a
|
||||
// single timeout to reject the Promise.all, reflect each one and once they've all
|
||||
// settled, filter for the fulfilled ones
|
||||
this.providers.map(provider =>
|
||||
provider
|
||||
.getCompletions(query, selection, force)
|
||||
.timeout(PROVIDER_COMPLETION_TIMEOUT)
|
||||
.reflect(),
|
||||
),
|
||||
);
|
||||
const completionsList = await Promise.all(this.providers.map(provider => {
|
||||
return timeout(provider.getCompletions(query, selection, force), null, PROVIDER_COMPLETION_TIMEOUT);
|
||||
}));
|
||||
|
||||
// map then filter to maintain the index for the map-operation, for this.providers to line up
|
||||
return completionsList.map((completions, i) => {
|
||||
if (!completions || !completions.length) return;
|
||||
|
||||
return completionsList.filter(
|
||||
(inspection) => inspection.isFulfilled(),
|
||||
).map((completionsState, i) => {
|
||||
return {
|
||||
completions: completionsState.value(),
|
||||
completions,
|
||||
provider: this.providers[i],
|
||||
|
||||
/* the currently matched "command" the completer tried to complete
|
||||
|
@ -102,6 +96,6 @@ export default class Autocompleter {
|
|||
*/
|
||||
command: this.providers[i].getCurrentCommand(query, selection, force),
|
||||
};
|
||||
});
|
||||
}).filter(Boolean);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import FlairStore from '../../stores/FlairStore';
|
|||
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||
import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks";
|
||||
import {Group} from "matrix-js-sdk";
|
||||
import {sleep} from "../../utils/promise";
|
||||
import {allSettled, sleep} from "../../utils/promise";
|
||||
|
||||
const LONG_DESC_PLACEHOLDER = _td(
|
||||
`<h1>HTML for your community's page</h1>
|
||||
|
@ -99,11 +99,10 @@ const CategoryRoomList = createReactClass({
|
|||
onFinished: (success, addrs) => {
|
||||
if (!success) return;
|
||||
const errorList = [];
|
||||
Promise.all(addrs.map((addr) => {
|
||||
allSettled(addrs.map((addr) => {
|
||||
return GroupStore
|
||||
.addRoomToGroupSummary(this.props.groupId, addr.address)
|
||||
.catch(() => { errorList.push(addr.address); })
|
||||
.reflect();
|
||||
.catch(() => { errorList.push(addr.address); });
|
||||
})).then(() => {
|
||||
if (errorList.length === 0) {
|
||||
return;
|
||||
|
@ -276,11 +275,10 @@ const RoleUserList = createReactClass({
|
|||
onFinished: (success, addrs) => {
|
||||
if (!success) return;
|
||||
const errorList = [];
|
||||
Promise.all(addrs.map((addr) => {
|
||||
allSettled(addrs.map((addr) => {
|
||||
return GroupStore
|
||||
.addUserToGroupSummary(addr.address)
|
||||
.catch(() => { errorList.push(addr.address); })
|
||||
.reflect();
|
||||
.catch(() => { errorList.push(addr.address); });
|
||||
})).then(() => {
|
||||
if (errorList.length === 0) {
|
||||
return;
|
||||
|
|
|
@ -1064,8 +1064,6 @@ const TimelinePanel = createReactClass({
|
|||
});
|
||||
};
|
||||
|
||||
let prom = this._timelineWindow.load(eventId, INITIAL_SIZE);
|
||||
|
||||
// if we already have the event in question, TimelineWindow.load
|
||||
// returns a resolved promise.
|
||||
//
|
||||
|
@ -1074,9 +1072,13 @@ const TimelinePanel = createReactClass({
|
|||
// quite slow. So we detect that situation and shortcut straight to
|
||||
// calling _reloadEvents and updating the state.
|
||||
|
||||
if (prom.isFulfilled()) {
|
||||
const timeline = this.props.timelineSet.getTimelineForEvent(eventId);
|
||||
if (timeline) {
|
||||
// This is a hot-path optimization by skipping a promise tick
|
||||
// by repeating a no-op sync branch in TimelineSet.getTimelineForEvent & MatrixClient.getEventTimeline
|
||||
onLoaded();
|
||||
} else {
|
||||
const prom = this._timelineWindow.load(eventId, INITIAL_SIZE);
|
||||
this.setState({
|
||||
events: [],
|
||||
liveEvents: [],
|
||||
|
@ -1084,11 +1086,8 @@ const TimelinePanel = createReactClass({
|
|||
canForwardPaginate: false,
|
||||
timelineLoading: true,
|
||||
});
|
||||
|
||||
prom = prom.then(onLoaded, onError);
|
||||
prom.then(onLoaded, onError);
|
||||
}
|
||||
|
||||
prom.done();
|
||||
},
|
||||
|
||||
// handle the completion of a timeline load or localEchoUpdate, by
|
||||
|
|
|
@ -136,6 +136,8 @@ class IndexedDBLogStore {
|
|||
this.id = "instance-" + Math.random() + Date.now();
|
||||
this.index = 0;
|
||||
this.db = null;
|
||||
|
||||
// these promises are cleared as soon as fulfilled
|
||||
this.flushPromise = null;
|
||||
// set if flush() is called whilst one is ongoing
|
||||
this.flushAgainPromise = null;
|
||||
|
@ -208,15 +210,15 @@ class IndexedDBLogStore {
|
|||
*/
|
||||
flush() {
|
||||
// check if a flush() operation is ongoing
|
||||
if (this.flushPromise && this.flushPromise.isPending()) {
|
||||
if (this.flushAgainPromise && this.flushAgainPromise.isPending()) {
|
||||
// this is the 3rd+ time we've called flush() : return the same
|
||||
// promise.
|
||||
if (this.flushPromise) {
|
||||
if (this.flushAgainPromise) {
|
||||
// this is the 3rd+ time we've called flush() : return the same promise.
|
||||
return this.flushAgainPromise;
|
||||
}
|
||||
// queue up a flush to occur immediately after the pending one
|
||||
// completes.
|
||||
// queue up a flush to occur immediately after the pending one completes.
|
||||
this.flushAgainPromise = this.flushPromise.then(() => {
|
||||
// clear this.flushAgainPromise
|
||||
this.flushAgainPromise = null;
|
||||
return this.flush();
|
||||
});
|
||||
return this.flushAgainPromise;
|
||||
|
@ -232,12 +234,16 @@ class IndexedDBLogStore {
|
|||
}
|
||||
const lines = this.logger.flush();
|
||||
if (lines.length === 0) {
|
||||
// clear this.flushPromise
|
||||
this.flushPromise = null;
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const txn = this.db.transaction(["logs", "logslastmod"], "readwrite");
|
||||
const objStore = txn.objectStore("logs");
|
||||
txn.oncomplete = (event) => {
|
||||
// clear this.flushPromise
|
||||
this.flushPromise = null;
|
||||
resolve();
|
||||
};
|
||||
txn.onerror = (event) => {
|
||||
|
|
|
@ -47,3 +47,20 @@ export function defer(): {resolve: () => {}, reject: () => {}, promise: Promise}
|
|||
|
||||
return {resolve, reject, promise};
|
||||
}
|
||||
|
||||
// Promise.allSettled polyfill until browser support is stable in Firefox
|
||||
export function allSettled(promises: Promise[]): {status: string, value?: any, reason?: any}[] {
|
||||
if (Promise.allSettled) {
|
||||
return Promise.allSettled(promises);
|
||||
}
|
||||
|
||||
return Promise.all(promises.map((promise) => {
|
||||
return promise.then(value => ({
|
||||
status: "fulfilled",
|
||||
value,
|
||||
})).catch(reason => ({
|
||||
status: "rejected",
|
||||
reason,
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue