简体   繁体   English

如何在JavaScript保证字符串中使用.then函数中的参数调用函数?

[英]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. 我正在转换用node.js编写的AWS lambda函数来使用promises而不是回调。 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. 我陷入了一个点,我有一个.then(),它返回一个值,我需要传递给我的一个函数,它已经被保证,以及其他参数。 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. 我发现的所有文章都解释了简单的promise链,它只通过.then()方法返回一个值。 None that then pass it into another promisified function. 没有,然后将其传递到另一个promisified函数。

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() ; 你可以使用Promise.all() .then()Function.prototype.bind() ; return rp.get() from getData() getData() return rp.get() 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. 使用promise时,您的代码看起来应该更像这样。

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!');
})
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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