2015-12-16 3 views
0

Я работаю над node.js с выраженной фреймворкой, и я пытаюсь вызвать несколько запросов mysql, и каждый запрос зависит от предыдущих запросов. Как выполнить запрос синхронно.Синхронный запрос с запросом mysql в nodejs

function f1(id, cb) { 
    $sql = "SELECT * FROM s1 where process_id=" +id; 

    connection.query(
     $sql, 
     function (err, result) {   
      if (err) { 
       cb(err, null); 
      } else { 
       var str = ''; 

       if (result.length > 0) { 
        for(val in result) { 
         $sql = "SELECT attribute_name FROM s2 where id=" + result[val].id; 

         connection.query(
          $sql, 
          function (err, attrresult) {   
           if (err) { 
            cb(err, null); 
           } else { 
            if (result.length > 0) { 
             str += attrresult[0].attribute_name; 
            } 
           } 
          } 
         );    
        } 
       } 

       cb('', str); 
      }     
     } 
    ); 
} 

router.get('/', function(req, res, next) { 
    f1('27', function (err,respose) { 
     console.log(respose); 
    }); 
}); 

Прошу предложить. Как мы можем это сделать.

Заранее спасибо.

ответ

0

Вы не можете сделать синхронный, но вы можете сделать его похожим на код синхронизации, используя обещания и генераторы.

function mySexyMethod() { 
    return new Promise(function (resolve, reject) { 
     someAsyncethod(params, function (err, data) { 
      if (err) { 
       return reject(err); 
      } 

      resolve(data); 
     }) 
    }); 
} 

Экспресс маршрутизатор

var wrap = require('co-express'); 

router.verb('some-route', wrap(function* (req, res, next) { 

    var val, val2; 

    try { 
     val = yield mySexyMethod(); 
     val2 = yield anotherPromiseThatRequiresPreviousVal(val); 
    } catch (e) { 
     return next(e); 
    } 
}); 

Еще лучше, если смотреть в https://www.npmjs.com/package/bluebird и проверить, если все, что MySQL Lib вы используете может быть promisified.

+0

В вашем решении 'mySexyMethod' и' anotherPromiseThatRequiresPreviousVal' будут выполняться параллельно. Вы не можете использовать результат первого во втором. Более того, ваше решение кажется неполным, потому что вы определяете свое обещание, но никогда не используете его. – Gnucki

+0

@ Gnucki - Nope. Он будет ждать. Смотрите, что «выход», он гарантирует, что все, что вы получили после этого, ждет. Я вроде как полностью использую 'mySexyMethod'. Посмотрите генераторы и обещания. Вы можете поблагодарить меня позже. –

+0

Извините, мой плохой, я слишком краснею и не видел, чтобы вы использовали 'co-express'. Это интересное решение. – Gnucki

0

вы можете использовать обещание цепочки или пакета асинхронной для обработки выполнения серии, шаг за шагом проверки ниже руководство по обетованию СЦЕПЛЕНИЕ https://coderwall.com/p/ijy61g/promise-chains-with-node-js

для асинхронной проверить следующий пакет https://github.com/caolan/async

0

Узел ввода/O по определению является асинхронным. Я думаю, что ваша проблема - цикл for. Он перебирает все итерации перед обратным вызовом вложенных запросов на соответствие переменной. Поэтому используйте некоторый механизм для достижения желаемого потока выполнения. Вы можете использовать обещания, есть несколько хороших библиотек (Q, Bluebird, родные обещания с ES2015 ...) Также вы можете использовать async.js, с которым легче справиться.

Библиотеки не являются обязательными, но они облегчают работу.

0

Как все говорили, Async.js - прекрасное решение для такого рода вещей.

Однако вначале это может быть немного сложно. Если вам нравится немного больше абстракции, я бы предложил вам использовать фреймворк, например, Danf (build on Express). Эта структура абстрагирует Async.js для обработки асинхронности (выполнять операции последовательно, параллельно, ...) оригинальным и простым способом. Взгляните на overview, чтобы понять, что я имею в виду.

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