多次调用 promise 会导致问题

时间:2021-03-26 06:59:59

标签: javascript jquery promise

由于异步 Ajax 调用,我们使用了 promise,以便其他等待 Ajax 成功对象的 JS 可以访问其更新的属性。

我们有 300 个 JS 会调用这个 promise,如果有这么多 JS 会调用 promise,我们是否有任何限制,它可能会开始挂起或永远不会解决。

请指教

提前致谢

(function () {
    window.myObject = window.myObject || {};
    let isProfileUpdated = false;

    myObject.waitforProfile = new Promise(function (resolve, reject) {
        let maxTry = 50;
        let currentTry = 0;
        let tryForProfile = function () {
            if (currentTry < maxTry && isProfileUpdated) {
                resolve();
            } else if (currentTry < maxTry) {
                currentTry++;
                setTimeout(tryForProfile, 350);
            }
            else {
                reject('profile never resolved');
            }
        }
        tryForProfile();
    });

    $.ajax({
        url: 'www.google.com',
            async: true,
            success: function (result) {
                result = result.model;
                if (result != undefined) {
                    window.myObject.title = result.title
                    isProfileUpdated = true;
                }
            }
        });

})();

调用者 - 我们有太多依赖 MyObject 属性的调用者

function initalizeNavigation() {
        if (myObject.title !== "") {
            createAuthenicatedUtilityNav();
        } else {
            createSignedOutUtilityNav();
        }
    }

    myObject.waitforProfile(initalizeNavigation)
        .catch(function (message) {
            console.log(message)
        });

1 个答案:

答案 0 :(得分:0)

在编写代码时遵循的算法中有几个错误。程序设计需要在丢弃和替换代码之前修复。一种设计方法可能是

  1. 创建一个全局 Promise 对象,以在前端收到 ajax 调用中从服务器请求的用户配置文件来实现。比如说profilePromise

  2. 发出 ajax 调用以获取用户配置文件。如果成功,请使用通知的错误或错误消息解析 profilePromisewith the decoded profile object. If it fails, rejectprofilePromise`。

  3. profilePromise 添加一个 catch 处理程序,以通知用户在被拒绝后重试(或其他)。发布的代码不会重试服务器调用,因此我没有尝试将其包含在此处。

  4. 如果时间过长,则设置超时以拒绝 profilePromise。如果计时器在 ajax 调用成功并完成承诺后回调尝试拒绝承诺,拒绝承诺将被简单地忽略 - 已解决的承诺状态和值是不可变的。

整个代码中的 300 多个代码点可以 await profilePromise 来获取用户配置文件,或者,调用 profilePromise.then 并带有要在其后使用配置文件对象调用的实现处理程序到货了。

代码点必须使用类似于

的语法处理 async 函数中的配置文件数据
const profile = await profilePromise;

或使用类似于

的语法添加一个履行处理程序来处理数据
profilePromise.then( profile => { do specific thing with profile data});

不能做的是“调用”promise,就好像它是一个获取配置文件的函数,或者创建一个同步函数,在它从服务器返回之前神奇地返回配置文件数据。< /p>

在步骤 3 中添加的 .catch 处理程序中进行错误检查。无需重新检查整个代码 - 执行处理程序永远不会被调用。


一种完全不同的方法可能是确保应用程序代码的关键部分在获取配置文件数据并将其放入全局变量之前不会执行。

在单页应用中,这可能涉及模态叠加或 HTML 的隐藏部分,以防止用户在被允许之前与代码进行交互。


请研究 async 函数和 await 运算符的使用,或者如果不熟悉它们,请使用其 then 方法将履行处理程序添加到承诺中。