Home Run two promises asynchronously, but prioritize the result of the first promise
Reply: 0

Run two promises asynchronously, but prioritize the result of the first promise

user3487
1#
user3487 Published in May 20, 2018, 3:39 pm

I'm developing an JS simple project that requires taking the json result (via fetch() or XHR) from 2 services. The first is the main service, and the second acts as a fallback. Each of them can be slower than the other (hint: it's a dictionary app, and 2 service is Wiktionary and Google Translate).

To get a little faster speed, I'm thinking it would be better if I get both of the results asynchronously (in parallel). It still prefer the result of service #1 whether it's fast or slow, and ignore (or abort) the service #2's task.

But if it failed to get the result of service #1, then the result of service #2 will be used as alternative. And because both services are run in parallel (from one point of time), service #2's result can be returned as fast as possible.

Please see my pseudo example here.

const setTimeOutP = (time, label, re = false) => {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      if(re == false)
        resolve(label);
      else
        reject(label);
    },time);
  });
};

promiseOneMustBeReturnedUnlessReject([setTimeOutP(1000, "promise 1"), setTimeOutP(3000, "promise 2")]); // Promise 1 (in 1s), similar to Promise.race

promiseOneMustBeReturnedUnlessReject([setTimeOutP(3000, "promise 1"), setTimeOutP(1000, "promise 2")]); // Promise 1 (in 3s)

promiseOneMustBeReturnedUnlessReject([setTimeOutP(1000, "promise 1", true), setTimeOutP(3000, "promise 2")]); // Promise 2 (in 3s), NOT 4s

promiseOneMustBeReturnedUnlessReject([setTimeOutP(4000, "promise 1", true), setTimeOutP(2000, "promise 2")]); // Promise 2 (in 4s), NOT 6s

promiseOneMustBeReturnedUnlessReject([setTimeOutP(4000, "promise 1", true), setTimeOutP(2000, "promise 2", true)]); // Reject in 4s

I have a dirty solution right now that I think it would work like I described:

const printResult = async (key) => {
    let dataObj = {
        wiktionary: {
            status: "pending"
        },
        googleTranslate: {
            output: "",
            status: "pending"
        }
    };

    wiktionary(key).then(result => {
        document.getElementById("result").innerHTML = result;
        dataObj.wiktionary.status = "printed";
    }).catch((error) => {
        if (dataObj.googleTranslate.status == "ready") {
            document.getElementById("result").innerHTML = dataObj.googleTranslate.output;
        } else if (dataObj.googleTranslate.status == "error") {
            throw new Error(error);
        } else {
            dataObj.wiktionary.status = "error";
        }
    });

    googleTranslate(key).then(result => {
        if (dataObj.wiktionary.status == "error") {
            document.getElementById("result").innerHTML = result;
            dataObj.googleTranslate.status = "printed";
        } else {
            dataObj.googleTranslate.output = result;
            dataObj.googleTranslate.status = "ready";
        }
    }).catch((error) => {
        if (dataObj.wiktionary.status == "error") {
            throw new Error(error);
        } else {
            dataObj.googleTranslate.status = "error";
        }
    });
};

But is there any more elegant way to handle this situation?

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.306758 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO