From c9f3a12693345a5e591f6518fdabbe453096e5df Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 13 Jul 2017 16:51:14 +0100 Subject: [PATCH] Fix Autocompleter promises Use bluebird instead of the now removed "q" library. Also, make sure we timeout and then `reflect` to effectively do an `allSettled` that waits for all promises to either be resolved or rejected. Then we filter for those that are fulfilled and return the completions. --- src/autocomplete/Autocompleter.js | 44 ++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/autocomplete/Autocompleter.js b/src/autocomplete/Autocompleter.js index 6b8cd66ae2..ec5d84f9a2 100644 --- a/src/autocomplete/Autocompleter.js +++ b/src/autocomplete/Autocompleter.js @@ -52,28 +52,30 @@ export async function getCompletions(query: string, selection: SelectionRange, f otherwise, we run into a condition where new completions are displayed while the user is interacting with the list, which makes it difficult to predict whether an action will actually do what is intended - - It ends up containing a list of Q promise states, which are objects with - state (== "fulfilled" || "rejected") and value. */ - const completionsList = await Q.allSettled( - PROVIDERS.map(provider => { - return Promise.resolve(provider.getCompletions(query, selection, force)) - .timeout(PROVIDER_COMPLETION_TIMEOUT); - }), + */ + 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 + PROVIDERS.map((provider) => { + // Convert to bluebird promise so that we can do a timeout + const p = Promise.resolve(provider.getCompletions(query, selection, force)); + return p.timeout(PROVIDER_COMPLETION_TIMEOUT); + }).map((p) => p.reflect()), ); - return completionsList - .filter(completion => completion.state === "fulfilled") - .map((completionsState, i) => { - return { - completions: completionsState.value, - provider: PROVIDERS[i], + return completionsList.filter( + (inspection) => inspection.isFulfilled(), + ).map((completionsState, i) => { + return { + completions: completionsState.value(), + provider: PROVIDERS[i], - /* the currently matched "command" the completer tried to complete - * we pass this through so that Autocomplete can figure out when to - * re-show itself once hidden. - */ - command: PROVIDERS[i].getCurrentCommand(query, selection, force), - }; - }); + /* the currently matched "command" the completer tried to complete + * we pass this through so that Autocomplete can figure out when to + * re-show itself once hidden. + */ + command: PROVIDERS[i].getCurrentCommand(query, selection, force), + }; + }); }