简体   繁体   中英

how to pass parameters in promise chain

I am really stuck with passing values between promises, I wonder if I can get a help here. I have a CustomerController calling methods in CustomerRepo

let getCustomers = customerRepo.getCustomers(req.query.offset, req.query.return);
let getProfiles  = customerRepo.getProfiles(rows);

getCustomers
   .then(function (rows) {
        console.log(rows[0]);
    })
    .then(getProfiles)

I do not know how to pass rows (array of customers) to getProfiles so I can populate the customers object with profiles. Here is the code in CustomerRepo -

var getCustomers = function (offset, _return) {
  return new Promise(function (resolve, reject) {
    var sqlString = 'call qsel_customers' + '(' + offset + ',' + _return + ')';
    pool.getConnection(function (err, connection) {
        if (err) {
            return reject(err);
        }
        connection.query(sqlString, function (err, rows) {
            if (err) {
                reject(err);
            }
            else
                resolve(rows);
            connection.release();

        });
        connection.on('error', function (err) {
            res.json({"code": 100, "status": "Error in connection database"});
        });
    });

  });
}

and for getProfiles

 var getProfiles = function (rows) {
  return new Promise(function (resolve, reject) {
     console.log(rows);
  }
}

I get rows undefined. Also please could someone suggest how can I extract the db mysql connection code into a dbConnect.js, to avoid code repetition.

Promise denotes the computation that may fail or not at some point in time. Therefore, in order to create a Promise you do:

return new Promise(function(resolve, reject) {
  // here you decide when the computation fails and when succeeds
  resolve(1) // success
  reject('error') // failed
})

Promise has a method (a swiss-knife, indeed) called then . It takes a function ƒ of one argument. Now, the magic of ƒ looks like this:

  • if ƒ returns simple value (string, number, array, etc) then it will wrap it in a new Promise and return it. The signature is then : Promise[a] -> (a -> b) -> Promise[b] . Therefore, say you have a function ∂ that returns a Promise of a number and ƒ takes a number and adds "!" to it, you and get this number, pass it to ƒ using then and end up with a new Promise:

    ƒ.then(n => n + '!') // Promise[String]

  • if ƒ returns a Promise, then then will "extract" the value if this Promise, pass it to ∂ and return a new Promise with the result. In pseudocode:

    ƒ.then(n => Promise(n + '!')) // Promise[String]

Okay, then returns a Promise. Well, let's design the code:

let getCustomers = () => Promise.resolve([ {}, {}, {} ])
// assume myApi.getProfile takes a Customer and returns a Profile
let getProfiles = (customers) => customers.map(myApi.getProfile)
getCustomers().then(getProfiles).then(console.log.bind(console));

I'm no expert in Promises but i don't think that it is good idea to put pool.getConnection inside your getCustomers promise. It looks like another promise and should be chained rather then combined.

Getting back to your main quersion. You can do this

getCustomers
.then(function (rows) {
 return getProfiles(rows); 
})
.then(function() {
console.log('get profiles resolved');
});

and

 var getProfiles = function (rows) {
  return new Promise(function (resolve, reject) {
     resolve(rows);
     console.log('other log of rows:' + rows);
  }
}

EDITED:

let getCustomers = customerRepo.getCustomers(req.query.offset, req.query.return);
let getProfiles  = customerRepo.getProfiles;

getCustomers
   .then(function (rows) {
        return getProfiles(rows);
    })
    .then(function(rows) {
     console.log('rows number ' + rows);
     console.log('get profiles resolved');           
     );

When chaining Promises, you have to return a Promise resolved with the value you're passing from the upstream function in order to use it in the downstream function.

getCustomers
  .then(function (rows) {
    console.log(rows[0]);
    return Promise.resolve(rows[0]);
  })
  .then(function(firstRow) {
    console.log("The first row's id is " + firstRow.id);
    return Promise.resolve(firstRow);
  })
  .then(getProfiles);

If you need to do asynchronous work in one of the functions, return a new Promise and invoke the resolve/reject functions as appropriate in the asynchronous callback. Promise.resolve() is a shortcut you can use if you're not doing anything asynchronously; it simply returns a Promise object resolved with the value it's passed.

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