从同步Node.js的问题 [英] Questions from the synchronous node.js

查看:241
本文介绍了从同步Node.js的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想同步的结果。结果
所有我想want'll除以5000个输入数据。结果
然而,由于异步的结果,上市很挣扎。结果
我希望看到同步Java等语言的结果。结果

我要的结果:

  100元素
承诺
100元
承诺
100元
承诺
100元
承诺

不过,code目前得到以下结果:

100元素
100元
100元
100元
100元




100元
承诺
承诺
承诺
承诺
承诺
承诺
承诺




承诺

我怎样才能得到这些结果?请帮帮我。谢谢。

  mysql.getConnection(函数(ERR,连接){  如果(ERR){connection.release();返回; }  变种数组= [];
  变种数= 300000;
  VAR长度=计数;  对于(VAR I = 0; I<计数;我++){    (函数(电流I,硕士){
      process.nextTick(函数(){        的Array.push([电流I,硕士]);        如果(%电流I 5000 === 0){
          的console.log('100元素');
          数组= [];          connection.beginTransaction(功能(错误){
            如果(ERR){
              扔犯错;
            }            VAR的查询=插入到用户(用户名,密码)值?            connection.query(查询,[阵列]功能(错了,行){              如果(!ERR){
                //提交启动
                connection.commit(函数(){
                  如果(ERR){
                    console.error(ERR);
                    connection.rollback(函数(){
                      console.error('回滚错误');
                      扔犯错;
                    });
                  }其他{
                    的console.log(提交);
                  } / /如果犯错
                    }); //提交结束
                }其他{
                                  的console.log(ERR);
                connection.rollback(函数(){
                  扔犯错;
                });
              } //如果
            })// cnnection查询
          }); //调用BeginTransaction
        } //如果      });
    }(我,'师父'));
  } //对
})//的getConnection


解决方案

有您可以在node.js中用于运行顺序异步操作的几个设计模式。在所有的人,你不能运行一个紧密循环,等待事情发生 - 你必须让node.js中运行的一个JavaScript线程,并给它尽可能多的周期尽可能

手动迭代

把code的迭代在本地函数(我通常把它叫做的next()),然后当一个迭代调用其去年完成的功能,你可以调用的next()再开始下一个循环。您可以通过测试一些条件,而不是调用的next()如果事情做或第一线的next()可以测试,看看你就大功告成了。

请参阅下面的code例如为您的code会是什么样子带手动迭代。

序承诺

如果您使用的承诺为您的异步操作,那么你可以让链式承诺为您做的所有测序在 P()。然后(F1)。然后(F2)。然后(F3) 。你可以看到这个答案是一个例子:<一href=\"http://stackoverflow.com/questions/32028552/es6-promises-something-like-async-each/32028826#32028826\">Promises像async.each 。

使用异步模块

借助异步模块支持许多异步管理功能。很多人觉得它非常有用 - 别人会preFER用承诺来解决类似的问题。在任何情况下,它有许多用于测序不同的功能。例如,如果你想异步遍历数组,你可以使用这样的:

  async.eachSeries(hugeArray,功能迭代器(项目,回调){
  如果(inCache(项目)){
    回调(NULL,缓存[项目]); //如果许多项目被缓存起来,你会溢出
  }其他{
    doSomeIO(项目,回调);
  }
}函数来完成(){
  // ...
});


这是你的code的版本,则使用自定义手动迭代的next()迭代函数。

 函数runQuery(回调){
    mysql.getConnection(函数(ERR,连接){
        如果(ERR){
            connection.release();
            回调(ERR);
            返回;
        }        变种数组= [];
        变种数= 10;
        变种索引= 0;        接下来的功能(){
            如果(指数++ LT;计数){
                的Array.push([指数,'大师']);
                的console.log('100元素');
                connection.beginTransaction(功能(错误){
                    如果(ERR){
                        //不能扔在这里异步函数
                        //使用回调沟通错误
                        回调(ERR);
                        返回;
                    }                    VAR的查询=插入到用户(用户名,密码)值?
                    connection.query(查询,[阵列]功能(错了,行){                        如果(!ERR){
                            //提交启动
                            connection.commit(函数(){
                                如果(ERR){
                                    console.error(ERR);
                                    connection.rollback(函数(){
                                        console.error('回滚错误');
                                        回调(ERR);
                                        返回;
                                    });
                                }其他{
                                    的console.log(提交);
                                    //现在做的下一次迭代
                                    下一个();
                                } //如果犯错
                            }); //提交结束
                        }其他{
                            的console.log(ERR);
                            connection.rollback(函数(){
                                回调(ERR);
                                返回;
                            });
                        } //如果
                    });
                });
            }
        }
    });
}

I would like synchronous results.
All I want'll want to enter data by dividing 5000 by one.
However, as a result of asynchronous listed it is struggling.
I want to see as a result of synchronous languages such as java.

I want these results:

100-elements
commit
100-elements
commit
100-elements
commit
100-elements
commit

However, the code currently gets these results:

100-elements
100-elements
100-elements
100-elements
100-elements
.
.
.
.
100-elements
commit
commit
commit
commit
commit
commit
commit
.
.
.
.
commit

How can I get these results? Please help me. Thank you.

mysql.getConnection(function(err, connection){

  if(err){ connection.release(); return; }

  var array = [];
  var count = 300000;
  var length = count;

  for(var i=0; i<count; i++){

    (function(currentI, master){
      process.nextTick(function(){

        array.push([currentI, master]);

        if(currentI % 5000 === 0){
          console.log('100-elements');
          array = [];

          connection.beginTransaction(function(err){
            if(err){
              throw err;
            }

            var query = "insert into users(username, password) values ?";

            connection.query(query, [array], function (err, rows) {

              if (!err) {
                //commit start
                connection.commit(function(){
                  if (err) {
                    console.error(err);
                    connection.rollback(function () {
                      console.error('rollback error');
                      throw err;
                    });
                  } else {
                    console.log("Commit");
                  }/ / if err
                    }); //commit end
                } else {
                                  console.log(err);
                connection.rollback(function(){
                  throw err;
                });
              } // if
            }) // cnnection query
          }); // beginTransaction
        } //if

      });
    }(i, 'master'));
  } //for
}) // getConnection

解决方案

There are a few design patterns you can use in node.js to run sequential asynchronous operations. In all of them, you cannot run a tight loop waiting for something to happen - you have to let the single Javascript thread in node.js run and give it as many cycles as possible.

Manual Iteration

Put the code for an iteration in a local function (I usually call it next()) and then when one iteration calls its last completion function, you can call next() again to start the next iteration. You can finish the operation either by testing some condition and not calling next() if things are done or the first lines of next() can test to see if you're done.

See the code example below for how your code would look like with manual iteration.

Sequence promises

If you use promises for your asynchronous operations, then you can let chained promises do all your sequencing for you as in p().then(f1).then(f2).then(f3). You can see an example of that in this answer: Promises like async.each.

Use the Async Module

The Async module supports a number of async management functions. Many find it very useful - others would prefer to use promises to solve similar problems. In any case, it has a number of different functions for sequencing. For example if you wanted to iterate an array asynchronously, you would use something like this:

async.eachSeries(hugeArray, function iterator(item, callback) {
  if (inCache(item)) {
    callback(null, cache[item]); // if many items are cached, you'll overflow
  } else {
    doSomeIO(item, callback);
  }
}, function done() {
  //...
});


Here's a version of your code that does the manual iteration using a custom next() iteration function.

function runQuery(callback) {
    mysql.getConnection(function(err, connection) {
        if (err) {
            connection.release();
            callback(err);
            return;
        }

        var array = [];
        var count = 10;
        var index = 0;

        function next() {
            if (index++ < count) {
                array.push([index, 'master']);
                console.log('100-elements');
                connection.beginTransaction(function(err) {
                    if (err) {
                        // can't throw here in an async function
                        // use callback to communicate error
                        callback(err);
                        return;
                    }

                    var query = "insert into users(username, password) values ?";
                    connection.query(query, [array], function(err, rows) {

                        if (!err) {
                            //commit start
                            connection.commit(function() {
                                if (err) {
                                    console.error(err);
                                    connection.rollback(function() {
                                        console.error('rollback error');
                                        callback(err);
                                        return;
                                    });
                                } else {
                                    console.log("Commit");
                                    // now do the next iteration
                                    next();
                                } // if err
                            }); //commit end
                        } else {
                            console.log(err);
                            connection.rollback(function() {
                                callback(err);
                                return;
                            });
                        } // if                    
                    });
                });
            }
        }
    });
}

这篇关于从同步Node.js的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆