javascript - 异步运行两个 Promise,但优先考虑第一个 Promise 的结果

标签 javascript asynchronous parallel-processing promise

我正在开发一个 JS 简单项目,需要从 2 个服务获取 json 结果(通过 fetch() 或 XHR)。第一个是主要服务,第二个是后备服务。它们中的每一个都可能比另一个慢(提示:它是一个字典应用程序,第二个服务是维基词典和谷歌翻译)。

为了获得更快的速度,我认为如果异步(并行)获得两个结果会更好。它仍然更喜欢服务 #1 的结果,无论它是快还是慢,并忽略(或中止)服务 #2 的任务。

但如果无法获取服务#1的结果,则将使用服务#2的结果作为替代。而且由于这两个服务是并行运行的(从一个时间点开始),因此可以尽快返回服务 #2 的结果。

请在此处查看我的伪示例。

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

我现在有一个肮脏的解决方案,我认为它会像我描述的那样工作:

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";
        }
    });
};

但是有没有更优雅的方法来处理这种情况?

最佳答案

您可以启动两个 Promise,然后在出现错误时返回后备:

const translate = key => {
    const fallback = googleTranslate(key);

    return wiktionary(key)
        .catch(() => fallback);
};

使用方式如下:

const printResult = async key => {
    const result = await translate(key);
    document.getElementById("result").innerHTML = result;
};

如果您有取消机制,请在 .then() 中、.catch() 之前使用它。

关于javascript - 异步运行两个 Promise,但优先考虑第一个 Promise 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49838925/

相关文章:

javascript - 由于类分配延迟,onclick 函数需要双击

Javascript 字符串赋值运算符

javascript - UIWebView 登录表单(iPad 应用程序)

asynchronous - Node.js TCP 客户端命令/响应

javascript - 如何在ajax回调中保留变量?

r - R (windows) 中大栅格的并行处理

algorithm - 如何为这个调度和资源分配问题建模

javascript - ui-grid-draggable-rows - 行不移动

c++ - 服务器关闭永远不会完成

c - OpenMP 基准并行计算