2015-11-05 2 views
3

Я использую Sails, Ватерлинию и асинхронной библиотекукак сделать работу контура с async.parallel()

function Outerfunction(listOfProducts) { 
    var salesOrderId = 1; //some id 
    var prom = []; 
    for (var i = 0; i < listOfProducts.length; i++) { 
    var qty = listOfProducts[i].quantity; 
    var prod = listOfProducts[i].productName; 
    var update = function(qty, prod, SalesOrderId) { 
     CardImages.update({ 
      where: { 
      productName: prod, 
      isSold: false, 
      readyToSell: true 
      } 
     }, { 
      order: SalesOrderId, 
      isSold: true 
     }) 
     .exec(function(err, updatedRecords) { 
      if (err) return err; 
      return updatedRecords; 
     }); 
    } 
    prom.push(update); 
    } 
    async.parallel(prom, function(err, result) { 

    //this callback never gets called 
    console.log("database calls done"); 
    }); 
} 

Я пытаюсь обновить базу данных для цикла, этот код работает отлично и обновление база данных, но мой обратный вызов с async.parallel не будет вызван, когда все записи будут обновлены.

+2

'async.parallel' принимает массив * функций *. Что возвращает 'exec'? Учитывая, что вы отметили это с помощью [обещания], кажется, вы ожидаете, что оно вернет обещание (afaik, только если вы не передадите обратный вызов 'exec') - поэтому вы хотите использовать' Promise.all (prom). Then (...) ', и не следует использовать async.js вообще! – Bergi

+1

или stick with 'async', очистить любое понятие обещаний, изменить имя участника« proms »на« tasks »и изменить функции, надавленные на' задачи', чтобы соответствовать [документации] (https: // github.com/caolan/async#parallel) –

+0

вместо использования цикла for я использовал функцию, счетчик и обратный вызов, но медленный, и я все еще ищу решение :) –

ответ

2

Функция, которую вы ищете, это async.map, которая будет применять асинхронную функцию к каждому элементу массива и перезвонить с массивом результатов. Я не могу проверить это, но что-то, как это должно работать:

function OuterFunction(listOfProducts) { 
    var salesOrderId = 1; // some id 

    async.map(listOfProducts, function (product, done) { 
    // for each product, update its DB entry 
    CardImages.update({ 
     productName: product.productName, 
     isSold: false, 
     readyToSell: true 
    }, { 
     order: salesOrderId, 
     isSold: true 
    }).exec(done); // indicate that async work is done 
    }, function (err, result) { 
    // all finished 
    console.log('database calls done'); 
    }); 
} 

Обратите внимание, что это решение не использует посылы на всех. Это просто асинхронная работа на основе обратного вызова.


Я не работал с ватерлинией, но на основе того, что я быстро нашел в (довольно плохой) документации, это также возможное решение:

function OuterFunction(listOfProducts) { 
    var salesOrderId = 1; // some id 
    // extract product names 
    var productNames = listOfProducts.map(function (product) { 
    return product.productName; 
    }); 

    // update in bulk 
    CardImages.update({ 
    productName: productNames, 
    isSold: false, 
    readyToSell: true 
    }, { 
    order: salesOrderId, 
    isSold: true 
    }).exec(function (err, results) { 
    // all finished 
    console.log('database calls done'); 
    }); 
} 

Перевода на SQL, первым решение будет излучать (примерно)

UPDATE table SET isSold = TRUE, readyToSell = FALSE 
WHERE productName = 'product 1' AND isSold = FALSE AND readyToSell = TRUE; 

UPDATE table SET isSold = TRUE, readyToSell = FALSE 
WHERE productName = 'product 2' AND isSold = FALSE AND readyToSell = TRUE; 

UPDATE table SET isSold = TRUE, readyToSell = FALSE 
WHERE productName = 'product 3' AND isSold = FALSE AND readyToSell = TRUE; 

... 

, а второй будет излучать более эффективным

UPDATE table SET isSold = TRUE, readyToSell = FALSE 
WHERE productName IN ('product 1', 'product 2', 'product 3', ...) 
    AND isSold = FALSE AND readyToSell = TRUE; 
+0

wow ... спасибо за ответ –

Смежные вопросы