Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用承诺强制执行特定的执行命令?_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 如何使用承诺强制执行特定的执行命令?

Javascript 如何使用承诺强制执行特定的执行命令?,javascript,node.js,promise,Javascript,Node.js,Promise,以下是程序代码: jobQueueManager.addSource=source=>{ console.log'addSource',source',source; 返回新的P 解析=>{ connection.beginTransactionerrorTransaction=>{ 如果错误事务{ 抛出新错误“启动事务时出错”; } connection.query'SELECT'id`来自'source',其中'country\u code`=?和'nid`=?'[ source.count

以下是程序代码:

jobQueueManager.addSource=source=>{ console.log'addSource',source',source; 返回新的P 解析=>{ connection.beginTransactionerrorTransaction=>{ 如果错误事务{ 抛出新错误“启动事务时出错”; } connection.query'SELECT'id`来自'source',其中'country\u code`=?和'nid`=?'[ source.countryCode, source.nid ],errorSelect,行=>{ 如果出错,请选择{ console.log'errorSelect',errorSelect; 抛出新错误“选择源时出错”; } //在第二次调用addSource后,应该能够找到该行 //使用相同的数据。但是因为第二次选择发生在第一次查询之前 //承诺,它没有。 日志“选择源”,“行”,行; 如果rows.length==0{ connection.query'INSERT-INTO'source'SET'{ 国家/地区代码:source.countryCode, nid:source.nid },errorInsert,结果=>{ 如果错误插入{ 抛出新错误“插入源时出错”; } console.log'insert source','source',source; resolveresult.insertId; }; }否则{ resolverows[0]。id; } }; }; } .thensourceId=>{ 返回新的预解决=>{ connection.committerrorcommit=>{ 日志'commit source'; 如果错误提交{ 抛出新错误“提交事务时出错”; } 决心{ id:sourceId, 来源 }; }; }; } .tapsourceEntity=>{ console.log'sourceEntity',sourceEntity; }; }; 以下是执行程序的说明:

许诺 .全部[ 作业队列管理器 .addSource{ 国家代码:“英国”, nid:‘福’ }, 作业队列管理器 .addSource{ 国家代码:“英国”, nid:‘福’ } , 作业队列管理器 .addSource{ 国家代码:“英国”, nid:‘福’ } ]; 以下是输出:

addSource source { countryCode: 'uk', nid: 'foo' }
addSource source { countryCode: 'uk', nid: 'foo' }
addSource source { countryCode: 'uk', nid: 'foo' }
select source rows []
select source rows []
select source rows []
insert source source { countryCode: 'uk', nid: 'foo' }
insert source source { countryCode: 'uk', nid: 'foo' }
insert source source { countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 2, countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 3, countryCode: 'uk', nid: 'foo' }
我希望执行命令是:

选择、插入; 选择 选择 但我得到了:

选择 选择 选择 插入 插入 插入
我做到这一点的唯一方法是使用执行队列,例如

jobQueueManager.addSource=source=>{ 让新闻来源; newSource=P.alljobQueueManager.addSource.executionQueue.then=>{ 返回新的P 解析=>{ // ... }; }; jobQueueManager.addSource.executionQueue.pushnewSource; 返回新闻源; }; jobQueueManager.addSource.executionQueue=[]; 这将产生预期的行为:

select source rows []
insert source source { countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
select source rows [ RowDataPacket { id: 1 } ]
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
select source rows [ RowDataPacket { id: 1 } ]
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }

看起来不像。在这种情况下,所有这些都能满足您的需要。那么,不要一次调用addSource三次,这样会让它们并行运行吗?使用then to chain来代替。你真的应该这样做,这就是你案例中的连接及其方法。您的addSource代码使用了可怕的回调风格,但它应该包含承诺。从异步回调抛出是一种反模式。@Bergi没有一种防弹的方法来保证节点mysql的连接。这里有一个完整的讨论,@GajusKuizinas:好吧,即使出于某种原因promisifyAll不容易工作,并且您必须手动promisify,您仍然应该promisify单个方法。addSource函数缺少任何抽象。这将导致内存泄漏,在该数组中永久保留每个调用的所有结果的承诺。@Bergi如果这是唯一的问题,只需添加just add executionQueue=executionQueue.FitlerPromission=>{return!promise.isImplemented;};。不,最明显的问题是:-另一个问题是,任何异常都将拒绝您的队列,并且您永远无法再次执行另一个addSource。有太多的边缘情况需要考虑。为什么Advand源需要对调用本身进行串行化,禁止任何并行执行?调用方不应该按照自己的要求对调用进行排序吗?顺便说一句,我已经成功地将事务强制逻辑移到了mysql库级别。这使得程序代码更加直观