Async is waiting for a promise

I need to wait until func1 function is running to start func2. But since func1 / 2/3 contains promises, it prints "ends" early.

async function executeAsyncTask () {
              const res1 = await func1(a,b,c)
              const res2 = await func2(a,b,c)
              const res3 = await func2(a,b,c)

              return console.log(res1 , res2 , res3 )
            }

executeAsyncTask ()

func1

class A{

    promise_API_CALL(params){
      //some code here..
    }

    func1(a,b,c){

    //so work here...

    this.promise_API_CALL(params, function( data, err ) {
       if(err){console.error(err)}
      console.log( data );
      return data;
    });

    //so work here...
    console.log("termined")


}

EDIT: prom_API_CALL is an external library function

+4
source share
4 answers

Try wrapping the api call in a promise. Otherwise, I do not see how this works the way you want:

func1(a, b, c) {
  return new Promise((resolve, reject) => {
    this.promise_API_CALL(params, function(data, err) {
      if (err) {
        console.error(err)
        reject(err);
      }

      console.log(data);
      resolve(data);
    });

    //so work here...
    console.log("termined")
  });
}
+4
source

To improve the code, the definition executeAsyncTaskshould be like this:

async function executeAsyncTask () {
  try {

    const res1 = await func1(a,b,c)
    const res2 = await func2(a,b,c)
    const res3 = await func3(a,b,c)

    return [res1, res2, res3]; // Return all values from 'each await' as an array

  } catch (err) {
      throw 'Promise Rejected';
  }
}

As you can see, it uses tryand catcheven for error handling. In other words, if one of the awaitfunctions rejected, it catchautomatically fails.

// This 'func1 code' from 'Carl Edwards' is the same
func1(a, b, c) {
  return new Promise((resolve, reject) => {
    promise_API_CALL(params, function(data, err) {
      if (err) {
        console.error(err)
        reject(err);
      }

      console.log(data);
      resolve(data);
    });

    //so work here...
    console.log("termined")
  });
}

, , executeAsyncTask :

executeAsyncTask().then(function(result) {
    console.log("result => " + result); // Result of 'res1, res2, res3'
}).catch(function(error) {
    console.log("error => " + error); // Throws 'Promise Rejected'
});

:

  • async Promise. await Promise, , Promise resolve reject s.

  • await , .


BONUS

, promises (func1, func2, func3) ( ), executeAsyncTask :

async function executeAsyncTask () {
  try {

    return [ res1, res2, res3 ] = await Promise.all([
        func1(a,b,c),
        func2(a,b,c),
        func3(a,b,c)
    ])

  } catch (err) {
      throw 'Promise Rejected';
  }
}
+1

, func1, :

async func1(a,b,c){
    const res = await promise_API_CALL(params, function( data, err ) {
       if(err){console.error(err)}
      console.log( data );
      return data;
    });

    console.log("termined");
    return res;
}

async function executeAsyncTask () {
  const res1 = await func1(a,b,c);
  const res2 = await func2(a,b,c);
  const res3 = await func2(a,b,c);
  //yada yada yada
}
0

Carl Edward answer, node.js '.

, promise_API_CALL() . util.promisify(). - node.js ' . :

const util = require("util");

promise_API_CALL[util.promisify.custom] = function (params) {
    return new Promise((resolve, reject) => {
        promise_API_CALL(params, function (data, err) {
            if (err) {
                return reject(err);
            }
            resolve(data);
        });
    });
};

The only problem I see is that it leads to a mutation of the original function (which does not belong to you and is a “strike” of a bit rough bad practice). But the problem is slightly mitigated, since it uses ES6 a new type of character , which should mean that you will not compress each other.

Here is a complete example:

const util = require("util");

/**
 * Use to force the API along the failure path
 * @constant {Boolean}
 */
const SHOULD_FAIL = false;

/**
 * Callback to deal with API responses
 * @callback apiCallback
 * @param {Object} data The data of the response
 * @param {Error} [err] Optional error that says something went wrong
 */

/**
 * Dummy API calling function
 * @param {Object} kwargs api arguments
 * @param {apiCallback} cb The callback that handles the response
 */
function apiCall(kwargs, cb) {
    setTimeout(() => {
        // Allow testing of failure path
        if (SHOULD_FAIL) {
            return cb(undefined, new Error("Purposefull failure"));
        }
        // Success path
        cb({
            foo: "bar"
        });
    }, 1000);
}

/*
 * Create a function that wraps the apiCall function in a Promise
 * and attach it to apiCall util.promisify.custom Symbol
 */
apiCall[util.promisify.custom] = function (kwargs) {
    return new Promise((resolve, reject) => {
        apiCall(kwargs, (data, err) => {
            if (err) {
                return reject(err);
            }
            resolve(data);
        });
    });
};

// Create shorthand function to the promisified function
const asyncApiCall = util.promisify(apiCall);

// Sanity check to make sure that they are the same
console.log(`Are promisifies the same? ${asyncApiCall === apiCall[util.promisify.custom]}`);

// Run tester function
(async function main() {
    // Do some stuff
    console.log("Started");

    // Use the async func
    let some_data_from_api;
    try {
        some_data_from_api = await asyncApiCall({
            fizz: "buzz"
        });
    } catch (err) {
        console.error(err);
    }

    // Print the data after we have it
    console.log(some_data_from_api);

    //so work here...
    console.log("Done")
}());
0
source

Source: https://habr.com/ru/post/1690083/


All Articles