Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function apply with Promises

I'm working on a promise-based project in Node.js using bluebird, and another in native promises by ES6. In both, I have a chain where I query a database in the following form:

some_function(/*...*/)

    .then(function () {
        return query("SELECT `whatever` FROM `wherever` ")
    })

    .then(/*...*/)

Note that query obviously returns a promise resolved to the query result. This repeats in several chains, and I'm looking for a way to clean up the unused function wrapper.

I'd naturally use Function.prototype.apply(), but in this case, when I try:

.then(query.apply(this, ["SELECT * FROM ... "]))
.then(function(rows){ /*...*/ })

The next function in the chain gets rows as undefined.

Thanks from ahead. Your help is appreciated.

like image 297
Selfish Avatar asked Aug 16 '15 17:08

Selfish


People also ask

How do you call a function after a Promise?

The Promise. all() method returns a single Promise that resolves when all of the promises passed as an iterable have resolved or when the iterable contains no promises. It rejects with the reason of the first promise that rejects. The data returned by Promise#all in the then callback is an array of your canvas s.

How do you write a function as a Promise?

To convert a callback into a promise, you need to return a promise. You run the code with the callback inside the promise. const readFilePromise = () => { return new Promise((resolve, reject) => { fs.

What is the function of Promise?

It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

Which methods can be used with Promise?

Promise has a pair of static methods, resolve and reject , to quickly create a new Promise with either a resolved or rejected value. This is handy when a function needs a Promise as an argument or as a return value.


2 Answers

You have to pass a function reference to .then() so your choices are as follows:

  1. Use an inline anonymous function as you are.
  2. Create your own utility function that returns another function (see example below)
  3. Use .bind() to create another function.

The inline anonymous

some_function(/*...*/).then(function () {
    return query.apply("SELECT `whatever` FROM `wherever` ")
}).then(/*...*/)

Your own function wrapper

function queryWrap(q) {
    return function() {
        return query.apply(q);
    }
}

some_function(/*...*/)
  .then(queryWrap("SELECT `whatever` FROM `wherever` "))
  .then(/*...*/)

This wrapper could be useful if you could use it in multiple places. Probably not worth it for just one invocation.

Use .bind()

some_function(/*...*/)
  .then(query.apply.bind(query, "SELECT `whatever` FROM `wherever` "))
  .then(/*...*/)
like image 173
jfriend00 Avatar answered Sep 20 '22 06:09

jfriend00


In es6, arrow functions solve this best:

.then(() => query.apply("SELECT `whatever` FROM `wherever` "))
.then(rows => { /*...*/ })
like image 30
jib Avatar answered Sep 22 '22 06:09

jib