添加插入查询时承诺停止工作
Promises stop working when adding a insertion query
询问有关节点 Q 库的承诺,mido 帮助我解决了承诺执行的问题 。基本上,解决方案(几乎)就是这段代码。
var form= [
{'name':'FORM_NAME_1.1',
'label2':'FORM_LABEL_1.2'
},
{'name':'FORM_NAME_2.1',
'label2':'FORM_LABEL_2.2'
}
];
var params = ['params1','params2'];
var meta = ['meta1','meta2'];
let process = (currentValue,index,arr) => {
//let reqCopy = {id: Math.random()}
let reqCopy = {};
for(let attr in req) // copy all the request attributes
//if(attr && attr!='id')
reqCopy[attr] = req[attr]
return Q.all([
Form.insert(connection,req,form[index],reqCopy),
Field.insert(connection,req,params[index],reqCopy),
Meta.insert(connection,req,meta[index],reqCopy)
])
}
return Q.all(form.map(process))
.catch((err) => console.log(err))
.done(() => console.log('Done'));
但现在我需要在第一个 promise (Form.insert)
中生成一个 id 并将其传递给其他人。使用 Node 的 mySql 库很容易获得插入行的 ID。这是承诺形式 Form
:
var Q = require('Q');
module.exports = {
insert: (connection,req,dataToInsert,reqCopy) => {
var deferred = Q.defer()
, db = 'DATABASE';
console.log('Form.insert is executing with data: ' + JSON.stringify(dataToInsert));
connection.query(`INSERT INTO ${db} SET ?`
,[dataToInsert]
,function(err, result) {
if (err) deferred.reject(err);
console.log('Result: ' + result.insertId);
deferred.resolve(result.insertId); //Return id when data was inserted
});
return deferred.promise;
}
}
但是现在,对于 INSERT INTO
查询,第一个承诺在流程结束时执行,再次失败:
//Promises are executed in the right order set in the .all array:
Form.insert is executing with data: {"name":"crf_NAME_1.1","label2":"FORM_LABEL_1.2"}
Field.insert is executing with data: "params1"
Meta.insert is executing with data: "meta1"
Form.insert is executing with data: {"name":"FORM_NAME_2.1","label2":"FORM_LABEL_2.2"}
Field.insert is executing with data: "params2"
Meta.insert is executing with data: "meta2"
//But Form.insert should generate the id before passing to the next promise.
C:\node\api\models\Form.js:17
console.log('Result: ' + result.insertId); //IT FAILS, SHOULD BE EXECUTED BEFORE
我不明白为什么会出现这种情况,因为 Form.insert 被定义为一个承诺并且 return 值(解决和拒绝)是在插入数据后设置的,所以流应该等待它的解决.
谢谢!
据我所知,如果操作相互独立,Q.all()
很有用。
如果是依赖项,您可以使用常规的 Promise 链接:
return Form .insert(connection,req,form[index],reqCopy)
.then((insertId) => {
return Q.all([
Field.insert(connection, req, insertId, params[index], reqCopy),
Meta .insert(connection, req, insertId, meta[index], reqCopy)
])
})
这假设Field.insert()
和Meta.insert()
仍然相互独立;如果没有,您可以使用相同的技巧将数据从前者传递到后者。例如,我将 insertId
作为插入方法的额外参数添加。
如果你想将第一个承诺的 id
传递给其他人,你可以这样做:
...
let process = (currentValue,index,arr) => {
return Form.insert(connection,req,form[index]).then(id => Q.all([
Field.insert(connection,req,params[index],id),
Meta.insert(connection,req,meta[index],id)
]))
}
...
询问有关节点 Q 库的承诺,mido 帮助我解决了承诺执行的问题
var form= [
{'name':'FORM_NAME_1.1',
'label2':'FORM_LABEL_1.2'
},
{'name':'FORM_NAME_2.1',
'label2':'FORM_LABEL_2.2'
}
];
var params = ['params1','params2'];
var meta = ['meta1','meta2'];
let process = (currentValue,index,arr) => {
//let reqCopy = {id: Math.random()}
let reqCopy = {};
for(let attr in req) // copy all the request attributes
//if(attr && attr!='id')
reqCopy[attr] = req[attr]
return Q.all([
Form.insert(connection,req,form[index],reqCopy),
Field.insert(connection,req,params[index],reqCopy),
Meta.insert(connection,req,meta[index],reqCopy)
])
}
return Q.all(form.map(process))
.catch((err) => console.log(err))
.done(() => console.log('Done'));
但现在我需要在第一个 promise (Form.insert)
中生成一个 id 并将其传递给其他人。使用 Node 的 mySql 库很容易获得插入行的 ID。这是承诺形式 Form
:
var Q = require('Q');
module.exports = {
insert: (connection,req,dataToInsert,reqCopy) => {
var deferred = Q.defer()
, db = 'DATABASE';
console.log('Form.insert is executing with data: ' + JSON.stringify(dataToInsert));
connection.query(`INSERT INTO ${db} SET ?`
,[dataToInsert]
,function(err, result) {
if (err) deferred.reject(err);
console.log('Result: ' + result.insertId);
deferred.resolve(result.insertId); //Return id when data was inserted
});
return deferred.promise;
}
}
但是现在,对于 INSERT INTO
查询,第一个承诺在流程结束时执行,再次失败:
//Promises are executed in the right order set in the .all array:
Form.insert is executing with data: {"name":"crf_NAME_1.1","label2":"FORM_LABEL_1.2"}
Field.insert is executing with data: "params1"
Meta.insert is executing with data: "meta1"
Form.insert is executing with data: {"name":"FORM_NAME_2.1","label2":"FORM_LABEL_2.2"}
Field.insert is executing with data: "params2"
Meta.insert is executing with data: "meta2"
//But Form.insert should generate the id before passing to the next promise.
C:\node\api\models\Form.js:17
console.log('Result: ' + result.insertId); //IT FAILS, SHOULD BE EXECUTED BEFORE
我不明白为什么会出现这种情况,因为 Form.insert 被定义为一个承诺并且 return 值(解决和拒绝)是在插入数据后设置的,所以流应该等待它的解决.
谢谢!
据我所知,如果操作相互独立,Q.all()
很有用。
如果是依赖项,您可以使用常规的 Promise 链接:
return Form .insert(connection,req,form[index],reqCopy)
.then((insertId) => {
return Q.all([
Field.insert(connection, req, insertId, params[index], reqCopy),
Meta .insert(connection, req, insertId, meta[index], reqCopy)
])
})
这假设Field.insert()
和Meta.insert()
仍然相互独立;如果没有,您可以使用相同的技巧将数据从前者传递到后者。例如,我将 insertId
作为插入方法的额外参数添加。
如果你想将第一个承诺的 id
传递给其他人,你可以这样做:
...
let process = (currentValue,index,arr) => {
return Form.insert(connection,req,form[index]).then(id => Q.all([
Field.insert(connection,req,params[index],id),
Meta.insert(connection,req,meta[index],id)
]))
}
...