当yield一个函数时(yield client.query),为什么函数的代码不执行?

when yield a function(yield client.query),why the codes of the function don't execute?

我试着用nodejs写了一些代码来读取mysql,我的代码是这样的:

exports.selectport = function*(projectname){
    var strsql = "SELECT DISTINCT portname FROM invoketable where projectname = '"+projectname+"'";
    var rest;
    yield 1;
    yield client.query(strsql, function(err, results) {
        if(err) {
           console.log(err);
           return err;
        }
        rest = results[0].portname;
        console.log(rest);
        return rest;
    });
    yield rest;
}

并且我使用代码调用函数:

var gen = mysqlinsertp.selectport(dataproject);
var ret = gen.next(); 
console.log(ret.value); // 1
console.log(ret.done); // false
var ret2 = gen.next();
console.log(ret2.value); // Query{...}
console.log(ret2.done); // false
var ret3 = gen.next(); 
console.log(ret3.value); // undefined
console.log(ret3.done); // false
var ret4 = gen.next(); 
console.log(ret4.value); // undefined
console.log(ret4.done); // true

我想知道为什么rest = results[0].portname; console.log(rest);没有执行

您似乎在混用生成器和回调。 你只会在以下情况下使用 yield: client.query(sql) return 是一个 promise 或一个 thunk,在这种情况下你不会使用上面显示的回调。

如果您使用的库没有 return promises 或 thunk,您需要:

// yieldable 
let results = yield client.query(sql);
// straight callback
client.query(sql, function(err, results){...});
  • 选择一个支持 promise // yieldable 的库
  • 围绕回调编写您自己的承诺包装器 // 易于查找
  • 只使用回调,而不是尝试产生 // 直接回调

此外,您 sql 容易受到 sql 注入攻击。如果用户指定项目名称,他们可以发送项目名称,如 junk'; DROP TABLE users;,在这种情况下,您将失去用户 table 或其他 tables... 您应该转义您的参数或参数化查询 connection.query('SELECT DISTINCT portname FROM invoketable where projectname ?', [project])