node.js - 我的同步功能不会等待所有子功能完成
问题描述
我正在尝试制作一个 api,它可以查看我是否在 imgur 上发了一个帖子,而且我真的快要完成了,但是我的函数在结束前返回
export.handler = (事件、上下文、回调) => {
ddb.scan(params1, function(err, data) {
if (err) callback(null, err);
else {
data.Items.forEach(function(item) {
for (var o = 0; item.links && item.links.L && o < item.links.L.length; o++) {
var taction = "";
var treaction = "";
var action = item.links.L[o].S.substring(0, item.links.L[o].S.indexOf(' '));
var saction = action.substring(0, action.indexOf(':'));
var reaction = item.links.L[o].S.substring(item.links.L[o].S.indexOf('=')+2);
var sreaction = reaction.substring(0, reaction.indexOf(':'));
for (var z = 0; item.accsplus && item.accsplus.L && z < item.accsplus.L.length; z++) {
if (item.accsplus.L[z].S.substring(0, item.accsplus.L[z].S.indexOf(':')) == saction)
taction = item.accsplus.L[z].S.substring(item.accsplus.L[z].S.indexOf('token:')+6);
if (item.accsplus.L[z].S.substring(0, item.accsplus.L[z].S.indexOf(':')) == sreaction)
treaction = item.accsplus.L[z].S.substring(item.accsplus.L[z].S.indexOf('token:')+6);
}
if (taction == "" || treaction == "") log += "no token for this service @" +action+reaction + " ";
else{
console.log("testing " +action+reaction)
if ((saction == "imgur" || saction == "reddit") && (sreaction == "imgur" || sreaction == "reddit")) {
if (saction == "imgur")
imgur(action.substring(action.indexOf(':')+1), item, taction, reaction.substring(reaction.indexOf(':')+1));
}
}
}
})
callback(null, "ok");
}
});
async function imgur(action, whom, token, reaction) {
if (action =="") return;
var requestdone = false;
var toret;
var old = "";
var needed = action;
if (action == "onpost" || action == "onrem") needed = "postnbr";
if (action == "onlike" || action == "ondis") needed = "likenbr";
console.log("imgur " + needed);
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer " + token);
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
async function request(success) {
const response = await fetch("https://api.imgur.com/3/account/me/images", requestOptions)
const json = await response.json();
return await success(json);;
}
function success(json) {
var worked;
if (needed == "postnbr") actual = (json.data.length);
if (needed == "likenbr"){
if (json.data[0].vote == null || json.data[0].vote == "null") actual = (0);
actual = (json.data[0].vote);
}
if (needed == "postnbr") console.log("postnbr = " + actual);
if (needed == "likenbr") console.log("likenbr = " + actual);
if (whom.old && whom.old.L && whom.old.L.length > 0){
for (var p = 0; old == "" && p < whom.old.L.length; p++){
if (whom.old.L[p].S.substring(0,whom.old.L[p].S.indexOf(':')) == "imgur"+needed)
{
old = whom.old.L[p].S.substring(whom.old.L[p].S.indexOf(':')+1);
if (action == "onpost" && old < actual) worked = true;
if (action == "onrem" && old > actual) worked = true;
if (action == "onlike" && old < actual) worked = true;
if (action == "ondis" && old > actual) worked = true;
}
}
}
if (worked)
{
return imgur(reaction, whom, token, "");
}
upold("imgur", needed, whom, actual)
}
await request(success)
}
var getactual = function(service, token, needed) {
return new Promise(function(resolve, reject){
if (service == "imgur"){
}
if (service == "reddit"){
console.log("do reddit mofo");
}
})
};
function upold(service, needed, whom, actual) {
var toret = [];
if (whom.old && whom.old.L.length > 0){
for (var m = 0; m < whom.old.L.length ; m++) {
if (whom.old.L[m].S.substring(0,whom.old.L[m].S.indexOf(':')) != service+needed)toret.push(whom.old.L[m].S);
}
}
toret.push(service+needed + ":" +actual);
param = {
TableName:"biipboop",
Key:{
"email": whom.email.S
},
UpdateExpression: "set old=:r",
ExpressionAttributeValues:{
":r":toret
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(param, function() {});
}
};
到目前为止,似乎该函数有效并且调用了请求子函数,但主函数不等待答案并返回 Promise {} 然后日志确实会在成功完成后发生,但我最后没有我的变量imgur 函数,它只是在完成时记录自己
已编辑:由于您要求提供我拥有的实际代码,因此我粗暴地复制粘贴了它并遍历foreach。
我正在尝试通过 aws 使用 lambda 和 ddb
日志确实按此顺序到达:
testing imgur:onpostimgur:onlike
imgur postnbr
testing reddit:postreddit:onpost
postnbr = 3
解决方案
你返回数据的方式imgur
对我来说真的很奇怪。在我看来,如果你变成imgur
一个async
函数,这样你就可以await
处理返回的数据,这会容易request
得多。
async function imgur(action, whom, token) {
var toret;
var old = "";
var needed = "postnbr";
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer " + token);
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
async function request(success) {
const response = await fetch("https://api.imgur.com/3/account/me/images", requestOptions)
const json = await response.json();
return /* await */ success(json); // <-- shouldn't have to await this
}
function success(json) {
old = "2";
if (needed == "postnbr") actual = (json.data.length);
if (needed == "postnbr") console.log("postnbr = " + actual);
if (action == "onpost" && old < actual)
return("you made a post recently");
updateold("imgur", needed, whom, actual)
}
return await request(success); // .then(function(msg) {return msg;});
}
然后你可以像这样使用它:
async function useImgur() {
const imgurData = await imgur('some-action', 'some-whom', 'some-token');
console.log(imgurData);
}
useImgur();
...或喜欢:
imgur('some-action', 'some-whom', 'some-token')
.then(imgurData => console.log(imgurData))
.catch(err => console.error(err));
推荐阅读
- java - 如何将异构 JSON 数组映射到 Java 对象?
- scala - 带有自定义验证的 Play Framework JSON 自动映射
- html - 常规菜单下方的 HTML 粘性导航栏
- python - Numpy random.choice 仅适用于小循环,但不适用于较大的循环
- arrays - 来自另一个表列的随机样本
- javascript - 如何删除 Firebase 中的帖子?
- pandas - 使用 pandas 验证超过 24 小时的时间格式
- twilio - 如何在 MVC 中使用 twilio 发送本地附件
- oracle - 如何在 Oracle Cloud 中复制 Oracle 数据库模式
- php - 您如何在 phpspreadsheet 中读取包含公式的文件?