雖然我有點想出了Koa流動機制如何工作(我認爲),但我似乎無法理解co和co.wrap之間的所有差異。這是給意外行爲代碼:Co和co.wrap在Node.js中的行爲有所不同
"use strict";
var co = require("co");
function ValidationError(message, obj, schema) {
Error.call(this, "Validation failed with message \"" + message + "\".");
this.name = "ValidationError";
this.object = obj;
this.schema = schema;
}
ValidationError.prototype = Object.create(Error.prototype);
function ValidatorWithSchema(properties, schema) {
this.properties = properties;
this.schema = schema;
}
ValidatorWithSchema.prototype.validate = function* (obj) {
var validatedObj = obj;
for (let schemaKey in this.schema) {
validatedObj = yield this.properties[schemaKey](validatedObj, this.schema[schemaKey]);
}
return validatedObj;
};
var typeGen = function* (obj, type) {
console.log("Checking against "+ type.name);
var primitives = new Map([
[String, "string"],
[Number, "number"],
[Boolean, "boolean"]
]);
if (!((obj instanceof type) || (primitives.has(type) && (typeof obj === primitives.get(type))))) {
var error = new ValidationError("Given object is not of type " + type.name, obj);
throw error;
}
return obj;
};
var validator = new ValidatorWithSchema({type: typeGen}, {type: String});
var runWrap = r => {
console.log(r);
console.log("### WRAP ###");
var validate = co.wrap(validator.validate);
validate(11).then(console.log, console.error);
};
co(function*() {
yield validator.validate(11);
}).then(runWrap, runWrap);
輸出到這個代碼如下:
Checking against String
{ [ValidationError] name: 'ValidationError', object: 11, schema: undefined }
### WRAP ###
11
你可以看到,我包使用co.wrap,以便爲它是隨後的簡單合作使用。現在很明顯typeGen
在第二次嘗試中沒有被調用,但爲什麼會出現這種情況?這兩個結果不應該完全相同嗎?
我想知道爲什麼'typeGen'是一個生成器?爲什麼你在這裏使用generator + co,似乎沒有任何異步?或者你打算做什麼? – Bergi
上面貼出的代碼是一個扁平模塊/測試對,它複製了令人費解的行爲。 –
是的,令人費解的行爲很容易解釋(請參閱下面的答案),但我認爲'typeGen'應該是一個承諾返回函數而不是生成器返回函數。 – Bergi