【问题标题】:Calling promise multiple times can Cause problems多次调用promise会导致问题
【发布时间】:2021-06-23 00:13:45
【问题描述】:

由于异步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)
        });

【问题讨论】:

  • 你不能称之为承诺。您的意思是代码中的 300 个点在进行相同的 Ajax 调用,将then 侦听器添加到单个承诺(或await 承诺)或其他什么?请在帖子中分享一些代码示例并附上解释。
  • @traktor 更新了我的问题,希望对您有所帮助

标签: javascript jquery promise


【解决方案1】:

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

  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,就好像它是一个获取配置文件的函数,或者制作一个同步函数,在配置文件数据从服务器返回之前神奇地返回它。

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


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

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


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

【讨论】:

    猜你喜欢
    • 2016-09-14
    • 2018-07-13
    • 2022-08-19
    • 2013-09-22
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    相关资源
    最近更新 更多