首页 > 解决方案 > 我的同步功能不会等待所有子功能完成

问题描述

我正在尝试制作一个 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

标签: node.jsapiasynchronouspromise

解决方案


你返回数据的方式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));

推荐阅读