在 nodejs bluebird 中 "request/ajax " 响应为 'success' 时解决或拒绝承诺
resolve or reject promise when "request/ajax " response is 'success' in nodejs bluebird
我不熟悉将 promises 与 bluebird 结合使用。
当状态响应从 api 更改为 "success" 时,我正在尝试解决承诺。
下面是我的代码:
exports.getdata(taskCreation, headers) {
var deferred = Promise.pending();
var headers = {
"Authorization": "Secret xxxxxxxxxxxxxxxxx"
};
while (true) {
request.get({
url: "https://dragon.stupeflix.com/v2/status",
qs: {
tasks: taskCreation[0]["key"]
},
headers: headers,
json: true
}, function (error, httpObj, taskStatusAndResult) {
if (!error && httpObj.statusCode == 200) {
console.log(taskStatusAndResult[0]["status"]); //contains either "queued", "executing", "success", or "error"
if (taskStatusAndResult[0]["status"] == "success")
deferred.resolve(taskStatusAndResult);
} else {
deferred.reject(error);
}
})
}
return deferred.promise;
}
api 需要几秒钟来处理视频,生成视频 url 并将状态设置为 "success"。在那之前我想重复调用 api,并且只有在以下情况下才解决承诺状态是 "success"。我的带有无限 while 循环的代码不起作用。关于如何以最佳方式实现此要求的任何建议。
您不能将 while()
循环与异步操作一起使用。它会在任何一个调用完成之前启动无数个 API 调用。相反,您必须对事物进行排序。打一个 API 电话。获得结果后,在该结果处理程序中决定下一步要做什么。
此外,您没有对您创建的承诺做任何事情,所以我决定 return 您的函数中的承诺。
而且,您的 exports.getData
声明不是正确的函数声明。
这是一个想法,你 return 一个承诺,如果你最终找到 "success" 状态,承诺就会被解决,如果出现错误情况,承诺就会被拒绝。
这实现了以下逻辑:
- 拨打 API 电话。收到回复后,请执行以下四项操作之一。
- 如果响应是错误的,则拒绝具有该错误的承诺
- 如果响应成功,用结果解决承诺
- 如果响应不是错误,但尚未成功并且您已超过最大重试次数,则拒绝最大重试次数
- 如果响应不是错误,但尚未成功并且您没有超过最大重试次数,请重试
- Return 来自函数的承诺,因此调用者可以仅在承诺上使用
.then()
来获取操作的结果或错误
代码如下:
exports.getdata = function (taskCreation, headers) {
var headers = {"Authorization": "Secret xxxxxxxxxxxxxxxxx"};
var cntr = 0;
var maxRetries = 20;
return new Promise(function (resolve, reject) {
function next() {
++cntr;
request.get({
url: "https://dragon.stupeflix.com/v2/status",
qs: {tasks: taskCreation[0]["key"]},
headers: headers,
json: true
}, function (error, httpObj, taskStatusAndResult) {
if (!error && httpObj.statusCode == 200) {
console.log(taskStatusAndResult[0]["status"]); //contains either "queued", "executing", "success", or "error"
if (taskStatusAndResult[0]["status"] === "success") {
// found success to resolve the promise
resolve(taskStatusAndResult);
} else {
// if not "success" yet, then try again
if (cntr > maxRetries) {
reject(new Error("max retries exceeded"));
} else {
// try again
next();
}
}
} else {
// got some kind of error here, so stop further processing
reject(error);
}
})
}
// start the first request
next();
});
}
你应该总是promisify在尽可能低的级别,这样你就可以对其他一切使用承诺。
function makeRequest() {
return new Promise(function(resolve, reject) {
request.get({
url: "https://dragon.stupeflix.com/v2/status",
qs: {
tasks: taskCreation[0]["key"]
},
headers: {
"Authorization": "Secret xxxxxxxxxxxxxxxxx"
},
json: true
}, function (error, httpObj, taskStatusAndResult) {
if (error) reject(error);
else if (httpObj.statusCode != 200) reject(httpObj); // or so
else resolve(taskStatusAndResult);
});
});
}
现在我们可以使用 promise 语法来编码您的应用程序用例,在本例中是一种递归算法,它会重试请求直到它获得 success
:
function getData(taskCreation, headers) {
return makeRequest(taskCreation, headers).then(function(taskStatusAndResult) {
if (taskStatusAndResult[0]["status"] == "success")
return taskStatusAndResult;
else
return getData(taskCreation, headers); // do it again
});
}
exports.getdata = getData;
我不熟悉将 promises 与 bluebird 结合使用。 当状态响应从 api 更改为 "success" 时,我正在尝试解决承诺。 下面是我的代码:
exports.getdata(taskCreation, headers) {
var deferred = Promise.pending();
var headers = {
"Authorization": "Secret xxxxxxxxxxxxxxxxx"
};
while (true) {
request.get({
url: "https://dragon.stupeflix.com/v2/status",
qs: {
tasks: taskCreation[0]["key"]
},
headers: headers,
json: true
}, function (error, httpObj, taskStatusAndResult) {
if (!error && httpObj.statusCode == 200) {
console.log(taskStatusAndResult[0]["status"]); //contains either "queued", "executing", "success", or "error"
if (taskStatusAndResult[0]["status"] == "success")
deferred.resolve(taskStatusAndResult);
} else {
deferred.reject(error);
}
})
}
return deferred.promise;
}
api 需要几秒钟来处理视频,生成视频 url 并将状态设置为 "success"。在那之前我想重复调用 api,并且只有在以下情况下才解决承诺状态是 "success"。我的带有无限 while 循环的代码不起作用。关于如何以最佳方式实现此要求的任何建议。
您不能将 while()
循环与异步操作一起使用。它会在任何一个调用完成之前启动无数个 API 调用。相反,您必须对事物进行排序。打一个 API 电话。获得结果后,在该结果处理程序中决定下一步要做什么。
此外,您没有对您创建的承诺做任何事情,所以我决定 return 您的函数中的承诺。
而且,您的 exports.getData
声明不是正确的函数声明。
这是一个想法,你 return 一个承诺,如果你最终找到 "success" 状态,承诺就会被解决,如果出现错误情况,承诺就会被拒绝。
这实现了以下逻辑:
- 拨打 API 电话。收到回复后,请执行以下四项操作之一。
- 如果响应是错误的,则拒绝具有该错误的承诺
- 如果响应成功,用结果解决承诺
- 如果响应不是错误,但尚未成功并且您已超过最大重试次数,则拒绝最大重试次数
- 如果响应不是错误,但尚未成功并且您没有超过最大重试次数,请重试
- Return 来自函数的承诺,因此调用者可以仅在承诺上使用
.then()
来获取操作的结果或错误
代码如下:
exports.getdata = function (taskCreation, headers) {
var headers = {"Authorization": "Secret xxxxxxxxxxxxxxxxx"};
var cntr = 0;
var maxRetries = 20;
return new Promise(function (resolve, reject) {
function next() {
++cntr;
request.get({
url: "https://dragon.stupeflix.com/v2/status",
qs: {tasks: taskCreation[0]["key"]},
headers: headers,
json: true
}, function (error, httpObj, taskStatusAndResult) {
if (!error && httpObj.statusCode == 200) {
console.log(taskStatusAndResult[0]["status"]); //contains either "queued", "executing", "success", or "error"
if (taskStatusAndResult[0]["status"] === "success") {
// found success to resolve the promise
resolve(taskStatusAndResult);
} else {
// if not "success" yet, then try again
if (cntr > maxRetries) {
reject(new Error("max retries exceeded"));
} else {
// try again
next();
}
}
} else {
// got some kind of error here, so stop further processing
reject(error);
}
})
}
// start the first request
next();
});
}
你应该总是promisify在尽可能低的级别,这样你就可以对其他一切使用承诺。
function makeRequest() {
return new Promise(function(resolve, reject) {
request.get({
url: "https://dragon.stupeflix.com/v2/status",
qs: {
tasks: taskCreation[0]["key"]
},
headers: {
"Authorization": "Secret xxxxxxxxxxxxxxxxx"
},
json: true
}, function (error, httpObj, taskStatusAndResult) {
if (error) reject(error);
else if (httpObj.statusCode != 200) reject(httpObj); // or so
else resolve(taskStatusAndResult);
});
});
}
现在我们可以使用 promise 语法来编码您的应用程序用例,在本例中是一种递归算法,它会重试请求直到它获得 success
:
function getData(taskCreation, headers) {
return makeRequest(taskCreation, headers).then(function(taskStatusAndResult) {
if (taskStatusAndResult[0]["status"] == "success")
return taskStatusAndResult;
else
return getData(taskCreation, headers); // do it again
});
}
exports.getdata = getData;