简体   繁体   中英

How do you call a function with parameters in a .then function in a JavaScript promise string?

I am converting my AWS lambda functions, written in node.js, to use promises instead of callbacks. I'm wrapping all of my functions in the handler with the handler code. I'm trying to break out simple functions so I can have as flat a promise chain as possible in the handler code.

I'm stuck at one point where I have a .then() that returns a value that I need to pass to one of my functions, which has been promisified, along with other parameters. I have searched high & low but can't find an example of the syntax to do this. I'm not even sure what I'm doing is the right thing at all. All of the articles I've found explain simple promise chains that only return a value through the .then() method. None that then pass it into another promisified function.

Here's what I have so far:

var bbPromise = require("./node_modules/bluebird");
var AWS = require("./node_modules/aws-promised");
var rp = require("./node_modules/request-promise");
var moment = require('./node_modules/moment.js');
var dynamodb = new AWS.dynamoDb();

exports.handler = function(event, context) { 
    "use-strict"; 

    // This gets a token that will be used as a parameter for a request
    function getToken(params){
        return rp.post({
            url: "https://api.something.com/oauth2/token",
            followRedirects: true,
            form: params,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        }).then(function(body){
            return JSON.parse(body).access_token;
        }).catch(function(error){
            console.log("could not get token: "+error);
        });
    }

    function getData(userId, db, token){ 
        var qParams = {
            // params that will get one record 
        };
        return dynamodb.queryPromised(qParams)
        .then(function (data){
            var start_date = // did some date manipulation on data to get this value
            // Request records, passing the token in the header
            var url = "https://api.something.com/data/?db="+db+"&start_date="+start_date;
            var headers = {
              'Content-Type': 'application/x-www-form-urlencoded',
              'Authorization':'Bearer '+token
            };
            tokenParams = {all the parameters};
            rp.get({
                url:url, 
                qs:tokenParams, 
                headers:headers, 
                followRedirect: true
            }).then(function(body){
                return body;
            }).catch(function(error){
                console.log("could not get data: "+error);
            });
        }).catch(function(error){
            console.log("Final Catch - getData failed: "+error);
        });
    }

    // THIS IS WHERE THE HANDLER CODE STARTS

    // Get an array of all userIds then get their data
    dynamodb.scanPromised({
        // params that will get the user Ids
    }).then(function(users){
        for(var i=0; i<users.length; i++){
            userId = // the value from the user record;        
            // Request a token
            var tokenParams = {an object of params};
            getToken(tokenParams)
            .then(function(token){
            ///////////// THIS IS WHERE I NEED HELP /////////////////
            /* Is there a way to pass getData the token within the .then() so I don't have a nested promise? */
                getData(userId, users[i].dbName, token)

            //////////////////////////////////////////////////////////
            }).catch(function (e){
                console.log("caught an error");
            });
        }
    }).catch(function (e){
        console.log("caught an error");
    });
};

You can use Promise.all() , .then() , Function.prototype.bind() ; return rp.get() from getData()

 return Promise.all(users.map(function(user) {
   userId = // the value from the user record;        
     // Request a token
     var tokenParams = {
       an object of params
     };
   return getToken(tokenParams)
     .then(getData.bind(null, userId, user.dbName))
     .catch(function(e) {
       console.log("caught an error");
       throw e
     });
 }))

When using a promise, your code should look more like this.

when.try(() => {
    return api.some_api_call
})
.then((results) => {
    const whatIAmLookingFor = {
        data: results.data
    };

    someFunction(whatIAmLookingFor);
})
.then(() => {
    return api.some_other_api_call
})
.then((results) => {
    const whatIAmLookingFor = {
        data: results.data
    };

    someOtherFunction(whatIAmLookingFor); 
.catch(() => {
    console.log('oh no!');
})
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM