Last active
October 20, 2020 15:54
-
-
Save davestewart/053e0c1bc859ffcd275df8ae88531aa4 to your computer and use it in GitHub Desktop.
Modify a function so it only resolves the last call
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// decorated search function | |
const search = last(function (query) { | |
return new Promise(function (resolve, reject) { | |
setTimeout(() => { | |
// randomly fail | |
Math.random() < .25 | |
? reject(new Error('failed for query ' + query)) | |
: resolve(String(query).toUpperCase()) | |
}, Math.random() * 2000) | |
}) | |
}) | |
// demo api | |
const api = { | |
loading: false, | |
async search (query) { | |
this.loading = true | |
const results = await search(query) // only the final call will resolve | |
this.loading = false | |
return results | |
} | |
} | |
// user types query, a..b..c... in real world, you would debounce this too | |
let query = '' | |
for (let i = 0; i < 10; i++) { | |
query += String.fromCharCode(97 + i) | |
api.search(query) | |
.then(result => { | |
console.log('result:', result) // result: ABCDEFGHIJ | |
}) | |
.catch(err => { | |
console.log('error:', err.message) // error: failed for query abcdefghij | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Decorate a function to resolve only the last call | |
* | |
* @param {Function} callback an asynchronous function | |
* @returns a decorated asynchronous function that resolves only the last call | |
*/ | |
function last (callback) { | |
let lastId = 0 | |
async function call (...args) { | |
const id = ++lastId | |
return Promise | |
.resolve(callback(...args)) | |
.then(result => { | |
return { id, result } | |
}) | |
.catch(error => { | |
return { id, error } | |
}) | |
} | |
return function (...args) { | |
return new Promise(async function (resolve, reject) { | |
return call(...args) | |
.then(function ({ id, result, error }) { | |
if (id === lastId) { | |
result | |
? resolve(result) | |
: reject(error) | |
} | |
}) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment