JavaScript Semaphores

0

How can I create semaphores in JavaScript? I have an asynchronous script that runs n times, I would like it when the n tasks terminate another task to be executed. I used normal access to a variable but this can cause race condition. Promise code:

var load_thumbs_promise = new Promise(function (resolve, reject) {
            var itens_id = formData.get('items_id');
            itens_id = itens_id.split(",");
            itens_id.forEach(function (item, index) {
                if(formData.get("type_" + item) == 'pdf')
                {
                    var pdf_url = formData.get("pdf_url_" + item);

                    PDFJS.getDocument(pdf_url).promise.then(function (doc) {
                        var page = [];
                        page.push(1);//Get first page

                        return Promise.all(page.map(function (num) {
                            return doc.getPage(num).then(makeThumb)
                                .then(function (canvas) {
                                    var img = canvas.toDataURL("image/png");

                                    formData.append("pdf_thumb_" + item, img);
                                    console.log(index);

                                    if(index == itens_id.length - 1)
                                    {
                                        console.log("d");
                                        resolve("It's done");
                                    }
                                });
                        }));
                    });
                }
            });
        });

How can I resolve this problem?

    
asked by anonymous 23.06.2017 / 15:21

1 answer

2

Change this forEach to a .map that returns a promise, so you have a promise for every Promise.all . Then you use this% w_that I put in the example to know when all Promises and sub-promises have been resolved.

var itens_id = formData.get('items_id');
itens_id = itens_id.split(",");
var itemsFetcher = itens_id.map(function(item, index) {
  if (formData.get("type_" + item) == 'pdf') {
    var pdf_url = formData.get("pdf_url_" + item);
    return new Promise(function(resolve, reject) {
        PDFJS.getDocument(pdf_url).promise.then(function(doc) {
          var page = [];
          page.push(1); //Get first page

          return Promise.all(page.map(function(num) {
            return doc.getPage(num).then(makeThumb)
              .then(function(canvas) {
                var img = canvas.toDataURL("image/png");

                formData.append("pdf_thumb_" + item, img);
                console.log(index);

                if (index == itens_id.length - 1) {
                  console.log("d");
                  resolve("It's done");
                }
              });
          }));
        });
      }
    });
});

Promise.all(itemsFetcher).then(res => console.log(res));
    
23.06.2017 / 15:40