javascript - 如何在 XMLHttpRequest 之后返回 Promise
问题描述
我在 Dynamics 365 中调用函数 enableButton 来启用/禁用按钮。我必须向系统返回一个 Promise。如果我执行一个返回 Promise 的简单测试函数,这可以正常工作,但我需要获取一个令牌,然后对服务进行外部调用以设置 true/false,然后返回 Promise。当我这样做时,它不起作用。似乎 Dynamics 从来没有从函数中得到承诺。
这是我的代码(我已经发布了一些细节)。我只在 Dynamics 中调用 enableButton()。
function enableButton() {
var params = getParams();
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://my.tokenendpoint.com");
xhr.onload = function () {
var token = JSON.parse(xhr.response).access_token;
getExternalData(token, ssn);
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(params);
}
function getExternalData(token) {
return new Promise(function (resolve, reject) {
var url = "http://example.com"
var query = JSON.stringify(
{
"queryparams": true
}
);
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.onload = () => {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
var hasExternalData = hasExtData(data[0]); //returns a boolean
resolve(hasExternalData);
}
else {
reject(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
reject(xhr.statusText);
};
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(query);
});
}
我已经使用 fetch 重写了代码,但我没有收到正确的数据以返回给 Dynamics。
如果我在 Dynamics 中使用这样的简单函数进行测试,它可以工作:
function enableButton() {
return new Promise(function (resolve, reject) {
var test = true;
resolve(test);
},
function (error) {
reject(error.message);
console.log(error.message);
}
);
}
如果我这样做,它不起作用:
function enableButton() {
fetch(accesstokenUrl, {
method: 'POST',
body: <omitted params>
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function (response) {
return response.json();
})
.then(function (resJson) {
return fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + resJson.access_token,
'Content-Type': 'application/json'
},
body: JSON.stringify(
{
"queryparams": true
})
});
})
.then(function (res) {
return res.json();
})
.then(function (data) {
const hasDebtCase = getDebtCase(data);
if (hasDebtCase) {
return Promise.resolve(hasDebtCase);
} else {
return Promise.reject(data);
}
})
.catch((error) => {
console.error('Error:', error);
})
};
我的问题是什么?
解决方案
在您的情况下,最好将 async/await 与fetch一起使用。
async function enableButton() {
const responseA = await fetch(accesstokenUrl, {
method: 'POST',
body: {
"access_token": "123"
},
});
const responseAJson = await responseA.json();
console.log("Response from the first fetch", responseAJson);
console.log("Your Access Token", responseAJson.access_token);
const responseB = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + responseAJson.access_token,
'Content-Type': 'application/json'
},
body: JSON.stringify(
{
"queryparams": true
})
});
console.log("Response from the second fetch", await responseB.json());
const hasDebtCase = getDebtCase(responseB.json());
if (hasDebtCase) {
return Promise.resolve(hasDebtCase);
} else {
return Promise.reject(data);
}
}
推荐阅读
- c++ - 使用 qt creator 设置 emscripten 编译器时出错
- python - 为什么我的 Ironpython 程序无法通过 MQTT 进行数据传输?
- pyspark - Pyspark ML - 随机森林分类器 - 一种热编码不适用于标签
- c# - 如何打开我的 C# 程序中的网页?
- r - 为什么输出,“if (set[i]%%j == 0) { 中的错误:需要 TRUE/FALSE 的缺失值”
- html - Angular 9 无法读取 MatSelect.ngAfterContentInit 中未定义的属性“管道”以用于 Mat Paginator
- flutter - 单子滚动视图不会在颤动中滚动
- node.js - 无法读取未定义的续集节点js express的属性用户名
- sql - ORA-00972 尝试更新表中的字段时
- python - 使用 scipy curve_fit() 将信号与背景拟合