如果后续承诺将根据条件返回,如何使用承诺链?
How to work with promise chains if the subsequent promises will be returned based on the condition?
我们有一个要求,我需要 运行 API-1。如果成功并且API响应的结果是'true',我需要运行API-2,如果成功并且API响应的结果是'true',我需要运行API-3。我尝试如下使用承诺链。
runMethodGeneric('A').then((data, status, xhr) => {
if(xhr.status === 200) {
if(data.result === 'true') {
runGenieMethodGeneric('B');
} else {
console.log('A result is false');
}
}
}).then((data, status, xhr) => {
console.log(data);
if(xhr.status == 200) {
if(data.result === 'true') {
runGenieMethodGeneric('C');
} else {
console.log('B result is false');
}
}
}).then((data, status, xhr) => {
console.log(data);
if(xhr.status === 200) {
if(data.result === 'true') {
console.log('C result is true');
} else {
console.log('C result is false');
}
}
}).catch((jqXhr, textStatus, errorMessage) => {
console.log(errorMessage);
});
运行MethodGeneric 是 运行 所有 API 的泛型方法,定义如下。
function runMethodGeneric(method) {
let url = 'http://192.168.1.253:55678/cl';
const json = {
user_data: data,
params: [],
gene_method: method,
requestedAction: 'RUN_GENIE_METHOD'
};
let jsonStr = JSON.stringify(json);
return $.ajax(url, {
type: 'POST',
dataType: 'JSON',
data: jsonStr,
});
}
我在 html 中使用 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js' 用于 jquery。
第一个 API 调用 'A' 正在工作,控制正在命中第一个 'then' 块,第二个 API 调用 'B' 被执行。当控件点击第二个 'then' 块时,数据、状态和 xhr 都未定义,即使第二个 API 调用 'B' 正在工作并获得正确的结果。
jQuery.Deferred exception: Cannot read property 'status' of undefined TypeError: Cannot read property 'status' of undefined
at http://localhost:5000/chat.js:95:10
at j (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js:2:29999)
at k (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js:2:30313) undefined
谁能帮我解决以下问题。
- 我想知道这是否是做 promise 链的正确方法?因为 运行MethodGeneric 函数 returns promise。但不确定如何使用 API 调用 B 和 C 返回的承诺,因为我正在根据结果调用那些 API 调用。
- 如果以上方法不正确,如何做满足要求的承诺链(运行 API-1。如果成功并且API响应的结果是'true', 运行 API-2, 如果成功并且API响应的结果为'true', 运行 API-3 )
- 我需要在 'then' 块中检查 xhr.status === 200 吗?我认为只有当 API 调用成功时,控制才会到达 'then' 块。这个假设是否正确?
基本上,你的函数 runMethodGeneric
return 一个 Promise
function runMethodGeneric(method) {
let url = 'http://192.168.1.253:55678/cl';
const json = {
user_data: data,
params: [],
gene_method: method,
requestedAction: 'RUN_GENIE_METHOD'
};
let jsonStr = JSON.stringify(json);
// HERE IS YOUR RETURN FUNCTION
return $.ajax(url, {
type: 'POST',
dataType: 'JSON',
data: jsonStr,
});
}
因此,当您执行此函数时,您需要 .then()
来解析来自此函数的响应
我想你可以在这里找到答案
您可以使用 async/await
语法和 for...of
循环来简化此操作,这样您就可以一个接一个地执行请求,您还可以将条件添加到 break
循环。
function fetchData(method) {
let url = `https://jsonplaceholder.typicode.com/todos/${method}`;
return $.ajax(url, {
type: 'GET'
});
}
async function runMethods() {
const methods = [1, 2, 'foo', 3, 4];
for (let method of methods) {
try {
const response = await fetchData(method);
// do your checking here
// break out of the loop if condition true
if (response.id == 3) {
console.log(response)
console.log('exiting on 3')
break;
} else {
console.log(response)
}
} catch (err) {
// you can also break on error here
console.log(`${err.status} for ${method} method`)
}
}
}
runMethods()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
我们有一个要求,我需要 运行 API-1。如果成功并且API响应的结果是'true',我需要运行API-2,如果成功并且API响应的结果是'true',我需要运行API-3。我尝试如下使用承诺链。
runMethodGeneric('A').then((data, status, xhr) => {
if(xhr.status === 200) {
if(data.result === 'true') {
runGenieMethodGeneric('B');
} else {
console.log('A result is false');
}
}
}).then((data, status, xhr) => {
console.log(data);
if(xhr.status == 200) {
if(data.result === 'true') {
runGenieMethodGeneric('C');
} else {
console.log('B result is false');
}
}
}).then((data, status, xhr) => {
console.log(data);
if(xhr.status === 200) {
if(data.result === 'true') {
console.log('C result is true');
} else {
console.log('C result is false');
}
}
}).catch((jqXhr, textStatus, errorMessage) => {
console.log(errorMessage);
});
运行MethodGeneric 是 运行 所有 API 的泛型方法,定义如下。
function runMethodGeneric(method) {
let url = 'http://192.168.1.253:55678/cl';
const json = {
user_data: data,
params: [],
gene_method: method,
requestedAction: 'RUN_GENIE_METHOD'
};
let jsonStr = JSON.stringify(json);
return $.ajax(url, {
type: 'POST',
dataType: 'JSON',
data: jsonStr,
});
}
我在 html 中使用 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js' 用于 jquery。
第一个 API 调用 'A' 正在工作,控制正在命中第一个 'then' 块,第二个 API 调用 'B' 被执行。当控件点击第二个 'then' 块时,数据、状态和 xhr 都未定义,即使第二个 API 调用 'B' 正在工作并获得正确的结果。
jQuery.Deferred exception: Cannot read property 'status' of undefined TypeError: Cannot read property 'status' of undefined
at http://localhost:5000/chat.js:95:10
at j (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js:2:29999)
at k (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js:2:30313) undefined
谁能帮我解决以下问题。
- 我想知道这是否是做 promise 链的正确方法?因为 运行MethodGeneric 函数 returns promise。但不确定如何使用 API 调用 B 和 C 返回的承诺,因为我正在根据结果调用那些 API 调用。
- 如果以上方法不正确,如何做满足要求的承诺链(运行 API-1。如果成功并且API响应的结果是'true', 运行 API-2, 如果成功并且API响应的结果为'true', 运行 API-3 )
- 我需要在 'then' 块中检查 xhr.status === 200 吗?我认为只有当 API 调用成功时,控制才会到达 'then' 块。这个假设是否正确?
基本上,你的函数 runMethodGeneric
return 一个 Promise
function runMethodGeneric(method) {
let url = 'http://192.168.1.253:55678/cl';
const json = {
user_data: data,
params: [],
gene_method: method,
requestedAction: 'RUN_GENIE_METHOD'
};
let jsonStr = JSON.stringify(json);
// HERE IS YOUR RETURN FUNCTION
return $.ajax(url, {
type: 'POST',
dataType: 'JSON',
data: jsonStr,
});
}
因此,当您执行此函数时,您需要 .then()
来解析来自此函数的响应
我想你可以在这里找到答案
您可以使用 async/await
语法和 for...of
循环来简化此操作,这样您就可以一个接一个地执行请求,您还可以将条件添加到 break
循环。
function fetchData(method) {
let url = `https://jsonplaceholder.typicode.com/todos/${method}`;
return $.ajax(url, {
type: 'GET'
});
}
async function runMethods() {
const methods = [1, 2, 'foo', 3, 4];
for (let method of methods) {
try {
const response = await fetchData(method);
// do your checking here
// break out of the loop if condition true
if (response.id == 3) {
console.log(response)
console.log('exiting on 3')
break;
} else {
console.log(response)
}
} catch (err) {
// you can also break on error here
console.log(`${err.status} for ${method} method`)
}
}
}
runMethods()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>