1

So, I'm super new to asynchronous and I cant understand how it works 'cause I can understand it but when I execute it, it seems that I didn't.

So, I have a code and I'm trying to run promises consecutively and carrying the variables and if it encounters an error it will go to catch.

Here's my simple code that I'm trying:

var x = new Promise(function(resolve, reject) {
var one = 1
    resolve(one)
    // if error happens go to catch
})
.then(function(value) {
var two = 2;
    resolve(two);
    // if error happens go to catch
})
.then(function(value) {
var three = 3;
    resolve(three);
    // if error happens go to catch
})
.then(function(value) {
console.log(one + two + three);
})
.catch(function(value) {
    // reverse all the execution
})

x;

I'm creating a promise which will

1st promise with for loops to contain some object to be inserted

2nd promise that will insert some rows to my 1st table

3rd promise that will insert some rows from 1st table and some results from the second promise

4th promise will finish up somethings, etc

and a catch that will delete data that is inserted and cut up by the error.

that is what I'm trying to imagine the logic, code, and execution.

I'm using mysql, btw. For someone who can help me, please, I need you. Thanksss

If you're curious of the real code I'm converting, this is what I made so far: https://pastebin.com/Ui5vcUDg

I'm using some just promise there and I'm thinking that if I use promise chaining, I can shorten or clean up my code.

Community
  • 1
  • 1
Cheryl Blossom
  • 185
  • 1
  • 13
  • 2
    Can you please show us your real code or real problem, not this made up code. Then, we can show you a proper way to solve an actual problem. This made up code doesn't make any sense because only the first call to `resolve()` is in scope of the argument `resolve ` so none of the others will even work. This is just a wild guess (because the code makes no sense), but probably what you want to do is to `throw someError` inside any of the `.then()` handlers to make it go to the `.catch()` at the end. – jfriend00 Feb 05 '19 at 12:45
  • BTW, if you want to return a value to the next promise just use `return`, not `resolve`. – Mosh Feu Feb 05 '19 at 12:48
  • Okay, you wished for it. Here: https://pastebin.com/Ui5vcUDg LMAO Thankssss – Cheryl Blossom Feb 05 '19 at 12:56

2 Answers2

1

Here's how you can pass values down promise chains, by creating an accumulator object which you then pass down, adding the result property in each step:

// Promises

var one = new Promise((resolve, reject) => {
  resolve(1)
})

var two = new Promise((resolve, reject) => {
  resolve(2)
})

var three = new Promise((resolve, reject) => {
  resolve(3)
})

// Promise Chain

one.then(one => {
  return ({ one })
})
.then(acc => {
  return two.then(two => ({ ...acc, two }))
})
.then(acc => {
  return three.then(three => ({ ...acc, three }))
})
.then(result => {
  console.log(result)
})
.catch(err => {
  console.error('one, two or three failed', err)
})

As for the error handling, if any of the returned Promises inside the Promise chain reject, the chain breaks and it's catch handler is triggered.

// Promises

var one = new Promise((resolve, reject) => {
  reject(new Error('Promise one error :('))
})

var two = new Promise((resolve, reject) => {
  resolve(2)
})

// Promise Chain

one.then(one => {
  return ({ one })
})
.then(acc => {
  return two.then(two => ({ ...acc, two }))
})
.then(result => {
  console.log(result)
})
.catch(err => {
  console.error(err)
})

You can also trigger the error yourself by throwing within a then:

var one = new Promise((resolve, reject) => {
  resolve(1)
})

var two = new Promise((resolve, reject) => {
  resolve(2)
})

one.then(one => {
  return ({ one })
})
.then(acc => {
  throw new Error('Error by explicit throw')
})
.then(acc => {
  return two.then(two => ({ ...acc, two }))
})
.then(result => {
  console.log(result)
})
.catch(err => {
  console.error(err)
})

Note:

two.then(two => ({ ...acc, two }))

is roughly the equivalent of:

two.then(two => {
  acc.two = two

  return acc
})

in case this syntax is confusing.

nicholaswmin
  • 21,686
  • 15
  • 91
  • 167
  • Does it mean I need to create the promises first before I can chain them? Sorry – Cheryl Blossom Feb 05 '19 at 13:09
  • 1
    @CherylBlossom Do your DB methods return Promises? Which node module are you using to communicate with your DB? If they are already returning Promises then you just need to chain them. If they are using callbacks then you need to wrap them in Promises. – nicholaswmin Feb 05 '19 at 13:10
  • I just use mysqljs, Im gonna need some last inserted keys and the object-like-array from loops. Here's my code so far. https://pastebin.com/Ui5vcUDg this is way messy and the promise I did is kinda I basically coded it but I dont understand how and why I did that. Sorry and thank you so much. – Cheryl Blossom Feb 05 '19 at 13:20
  • 1
    Yeah so it doesn't seem to support Promises so you're gonna have to wrap each `db.query` in a Promise if you want to work with Promises. – nicholaswmin Feb 05 '19 at 13:21
  • Oooh I see. Do you have recommendation any node module for mysql that is like php way for communicating database or much easy way that I can use next time? but for real thank you so so so so much and sorry for being annoying. – Cheryl Blossom Feb 05 '19 at 14:20
  • @CherylBlossom No worries, you are not annoying. Yes there's [promise-mysql](https://www.npmjs.com/package/promise-mysql), which is a wrapper to the library you're already using that actually returns Promises if that's what you mean. I don't know what the PHP way is, but I'm guessing you mean non-asynchronous; which is a no-go in Node.js. – nicholaswmin Feb 05 '19 at 14:22
  • "*I need to create the promises first before I can chain them?*" - no you can (and should) create them where you need and use them, i.e. the `Promise.resolve(2)` inside the `then` handler. – Bergi Feb 05 '19 at 14:32
0

In callbacks, that you put into "then", you don't need to call resolve() to invoke the next step of the chain. You just need to return some value and the next step of the chain will receive it as its argument.

You probably mixed up the way promises are created and chained. When you create a promise, you provide to its constructor a callback, arguments of which are "resolve" and "reject", which are also callbacks. They are expected to be invoked by the code inside the callback inside the promise constructor. When you invoke resolve, the promise will resolve with the value you provide to resolve. The same with reject.

This topic is definitely confusing, I recommend you to take a closer look on how people chain promises and how people create custom promises.

Vladyslav Usenko
  • 2,296
  • 8
  • 18