传统上,旧版 Web 客户端需要某些扩展(如功能区规则)同步返回,这意味着开发人员在从远程源请求数据时被迫使用同步请求。在统一接口中,我们已采取措施确保支持异步通信。例如:
- 统一接口支持异步功能区规则评估。
- 统一接口支持异步 OnLoad 和 OnSave。
- 许多客户需要使用 Xrm.Utility.getGlobalContext().userSettings.securityRoles 检查权限,遍历集合以从 Dataverse 请求角色名称。我们已将角色属性添加到用户设置,以避免需要请求角色名称。
- 我们正在对网格项图标进行异步评估。
现在,运行解决方案检查器将提醒您任何检测到的具有 Web 使用异步规则的同步请求。
例子
让我们看一个实际的例子。如前所述,同步请求通常用于功能区规则,因为旧版 Web 客户端仅支持此策略。
// NOTE: Don't do this!
function EnableRule() {
const request = new XMLHttpRequest();
// Pass false for the async argument to force synchronous request
request.open('GET', '/bar/foo', false);
request.send(null);
return request.status === 200 && request.responseText === "true";
}
规则逻辑要求服务器提供一些数据,对其进行分析,并返回一个布尔值作为其规则评估结果。同样,这会冻结最终用户的浏览器,直到请求从服务器返回。
让我们看看如何将此规则从同步转换为异步。通过将请求处理程序包装在 Promise 中并在请求完成时解析或拒绝,该规则不会阻止浏览器执行更多工作。当然,在实践中,您可能会使用帮助程序来包装这些类型的请求,因此不需要复制 Promise 代码。
function EnableRule() {
const request = new XMLHttpRequest();
request.open('GET', '/bar/foo');
return new Promise(function(resolve, reject) {
request.onload = function (e) {
if (request.readyState === 4) {
if (request.status === 200) {
resolve(request.responseText === "true");
} else {
reject(request.statusText);
}
}
};
request.onerror = function (e) {
reject(request.statusText);
};
request.send(null);
});
}
使用承诺和异步模式,用户现在可以在请求获取数据时自由地与页面交互。页面加载时不再冻结用户界面!
下面是使用用户设置的新角色属性来避免同步请求的另一个示例。
// NOTE: Don't do this!
function userHasRole(roleName) {
const roleIds = Xrm.Utility.getGlobalContext().userSettings.securityRoles;
let hasRole = false;
roleIds.forEach(function(roleId) {
const request = new XMLHttpRequest();
// Pass false for the async argument to force synchronous request
request.open('GET', '/api/data/v9.0/roles(' + roleId + ')', false);
request.send(null);
if (request.status === 200) {
const result = JSON.parse(request.responseText);
if (result.name === roleName) {
hasRole = true;
}
}
});
return hasRole;
}
使用统一接口提供的新角色功能,根本不需要发出网络请求:
function userHasRole(roleName) {
const matchingRoles = Xrm.Utility.getGlobalContext().userSettings.roles.get(function(role) {
return role.name === roleName;
});
return matchingRoles.length > 0;
}
下面是上述更改之前和之后的网络请求配置文件(假设用户有 10 个角色)。
之前(~2.3 秒):
之后(~1.2 秒):
您可以看到超过 1 秒 (~50%) 的表单加载被削减,并且内容在没有同步请求的情况下呈现得更快!
原文参照:https://powerapps.microsoft.com/zh-cn/blog/turbocharge-your-model-driven-apps-by-transitioning-away-from-synchronous-requests/