make the for loop do tasks in order in node js

197
June 27, 2017, at 01:14 AM

ctx.reply is not run in order despite i use .then()../ how could i fix it// i attach a picture for better understanding

bot.hears('کلید ها', (ctx) => {
    request('http://127.0.0.1:8080/json.htm?type=command&param=getlightswitches', function (error, response, body) {
        if (error == null) {
            inputdevices = JSON.parse(body)
            for (var key in inputdevices.result) {
                ctx.reply(`${inputdevices.result[key].Name}`, Extra.HTML().markup((m) =>
                    m.inlineKeyboard([
                        m.callbackButton(`روشن`, `روشن کلید <%>${inputdevices.result[key].idx}<%> <#>${inputdevices.result[key].Name}<#>`),
                        m.callbackButton(`خاموش`, `خاموش کلید <%>${inputdevices.result[key].idx}<%> <#>${inputdevices.result[key].Name}<#>`)
                    ])
                )) .then(() => ctx.reply("*****************"))
            }
        }
        else {
            console.log("ارتباط با دیتابیس برقرار نشد ، لطفا دوباره تلاش کنید");
            ctx.reply("ارتباط با دیتابیس برقرار نشد ، لطفا دوباره تلاش کنید")
        }
    })
})

look at this picture here

Not in order:

Answer 1

Assuming ctx.reply() is returning a Promise, you need to chain together all of the Promises.

Instead of using a for loop, do something like have a recursive function that calls things one at a time. It looks like you don't use key directly, so we'll also map to an array first to simply things:

const arr = Object.keys(inputdevices.result).map(key => inputdevices.result[key]);
const replyNext = () => {
  if (!arr.length) return Promise.resolve();
  const inputDevice = arr.shift();
  return ctx.reply(${inputDevice.Name}, Extra.HTML().markup((m) =>
    m.inlineKeyboard([
      m.callbackButton(روشن,روشن کلید <%>${inputDevice.idx}<%> <#>${inputDevice.Name}<#>),
      m.callbackButton(خاموش,خاموش کلید <%>${inputDevice.idx}<%> <#>${inputDevice.Name}<#>)
    ])
  )).then(() => ctx.reply("*****************"))
  .then(replyNext);
}

This should cause one reply to go, wait for it to finish, then trigger the next, until you've done them all.

This does put them in parallel, which will make it slower than necessary, but it'll keep it in order. If order doesn't matter, then use Promise.all() and map them all to Promises:

Promise.all(
  Object.keys(inputdevices.result)
    .map(key => /* contents of your for loop, return promise */)
).then(() => console.log('all done'));
READ ALSO
Socket.io &ldquo;Session ID unknown&rdquo; error on Heroku

Socket.io “Session ID unknown” error on Heroku

I have a Node JS app using Socketio deployed to heroku

337
How to add jwt auth to swagger (node + express)?

How to add jwt auth to swagger (node + express)?

I create project like this: https://scotchio/tutorials/speed-up-your-restful-api-development-in-node-js-with-swagger

226
Is there a way to create DOM elements on the back end for your frontend?

Is there a way to create DOM elements on the back end for your frontend?

I'm using a NodeJS server with Express and I want to create a new DOM element whenever a user decides to be active and delete them when they aren'tThe active user should be global to everyone

175