我已向 API 发出 HTTP PUT 请求,该请求返回的响应状态为“等待”。我想继续使用 HTTP GET 请求轮询 API,直到状态更改为“完成”。我在 NodeJS 中使用 Promise,但尚未找到持续轮询我的请求的解决方案。
我尝试过使用 setTimeout() 来使用 Promise Chaining,但这不会轮询 API,而是请求与我编写 HTTP GET 代码一样多的次数。我想使用类似的东西:
while(JSON.parse(response.body).result.info.state != "finished")
{
//keep polling
}
我应该在 API 控制台上看到轮询 GET 请求,但 while 循环只运行一次。
startRequest(request, reply) {
console.log("startRequest() is fired")
return new Promise((resolve, reject) => {
setTimeout(function () {
Request.put({ //making a PUT request (i have done require('request'))
headers: {
"SessionID": request.payload.session
},
url: "http://" + API - IP + ":" + API - PORT + "/upload/" + request.payload.filenameWithoutExtension,
}, (error, response) => {
if (error)
reject(error);
else {
var state = JSON.parse(response.body).result.info.state;
var pendingid = JSON.parse(response.body).result.info.id;
console.log("response.body", response.body)
resolve(state + ":" + pendingid);
}
})
}, 3 * 1000)
}).then(response => { //then with response making a GET request
var infoArray = response.split(":")
var pendingid = infoArray[1];
return new Promise(function (resolve, reject) {
console.log("Polling() is fired")
while (state != "finished") {
Request.get({
headers: {
"SessionID": request.payload.session
},
url: "http://" + API - IP + ":" + API - PORT + "/pending/" + pendingid,
}, (error, response) => {
if (error)
reject(error);
else {
state = JSON.parse(response.body).result.info.state;
return state;
}
})
}
}
}
}
一般来说,达到效果
while(variable !== value){
asynchronousFunction(callback(){
});
}
正如预期的那样,如果 asynchronousFunction 同步执行,您可以使用 ;
f(){
if(variable !== value){ // do the loop condition test
asynchronousFunction(callback(){ //call the loop contents
variable = updated_value ;// set the condition variable in the callback - ie. when asynchronousFunction is done. then..
f() // call again - ie. loop with the updated condition variable
});
}
}
f() ; // start the loop
尽管由于 Promise 和超时,事情变得有点复杂;
尝试
startRequest(request, reply) {
console.log("startRequest() is fired")
const pollingDelay = 1000 ;
let state = null ;
let pendingid = null ;
return new Promise((resolve, reject) => {
Request.put({ //making a PUT request (i have done require('request'))
headers: {
"SessionID": request.payload.session
},
url: "http://" + API - IP + ":" + API - PORT + "/upload/" + request.payload.filenameWithoutExtension
}, (error, response) => {
if (error)
reject(error);
else {
state = JSON.parse(response.body).result.info.state;
pendingid = JSON.parse(response.body).result.info.id;
console.log("response.body", response.body)
resolve(state + ":" + pendingid);
}
});
}).then(response => { //then with response making a GET request
return new Promise(function (resolve, reject) {
function pollState(){
console.log("Polling...")
Request.get({
headers: {
"SessionID": request.payload.session
},
url: "http://" + API - IP + ":" + API - PORT + "/pending/" + pendingid
}, (error, response) => {
if (error)
reject(error);
else {
state = JSON.parse(response.body).result.info.state;
continueCheckingForCompletion();
}
});
}
function continueCheckingForCompletion(){
if(state !== "finished")){
setTimeout(pollState,pollingDelay);
}
else{
resolve(state);
}
}
continueCheckingForCompletion();
});
});
}
免责声明
这段代码(OP代码的修改)只是为了解决重复调用异步函数(get)直到满足给定条件(state ===“finished”)的问题。
它是否是适合任务的正确代码取决于请求包和服务器 API 的具体情况。
注释
检查“待处理”端点是否“已完成”似乎并不直观。此外,如果提交被接受但由于某种原因未随后完成,“待处理”端点将需要引发错误以指示该过程已失败,否则轮询将无限期地继续。
对于此类客户端使用,更直观的 RESTful API 是;
/upload/<upload info> //success returns submission id
/status/<submissionId> // success returns current status - used for polling
/pending/[target identifier] //returns 404 - not here or the target if present in pending or discovery info if no target identifier.
/finished/[target identifier] //returns 404 - not here or the target if present in finished or discovery info if no target identifier.
我是一名优秀的程序员,十分优秀!