我搜索了ES6发生器的真实情况并没有找到正确的解释。我试图理解第一个承诺场景。
假设我们有2个休息时间: getUser 和 getUserComments
我们不想创建一个线性代码结构,以避免嵌套然后回调功能。所以...
定义模拟apis
function getUser () {
return new Promise(function(resolve, reject) {
return setTimeout(function() { resolve({id: 1, label: 'John'}); }, 200);
});
}
function getUserComments(userId) {
return new Promise(function(resolve, reject) {
return setTimeout(function() {resolve({comments: 'comments', userId: userId}); }, 200);
});
}
定义生成器
function* generator () {
yield getUser();
yield getUserComments(userId); // userId represents data from first request / first yield how should I pass it ?!
}
var g = generator();
var first = g.next(1);
var second = g.next(2);
如何从第一个yield获得响应(yield getUser())并将其传递给下一个yield(yield getUserComments(userId))?
答案 0 :(得分:1)
您可以将产生的结果分配给变量:
next()方法还接受一个值,该值可用于修改生成器的内部状态。传递给next()的值将被视为暂停生成器的最后一个yield表达式的结果。 (来自MDN, Advanced generators )
然后,由于您正在处理Promises,因此使用async / await将其解包为值是有意义的。
试试这个(我更正了setTimeout参数):
async function getUser() {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 0, {
id: 1,
label: 'John'
})
})
};
async function getUserComments(user) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 0, {
...user,
comments: 'comments',
}, 'userComments');
});
}
function* generator () {
const user = yield getUser();
yield getUserComments(user);
}
(async function () {
const g = generator();
const user = await g.next().value
const comments = await g.next(user).value
console.log(comments)
})()
答案 1 :(得分:1)
有人指出,必须等待或链接承诺(then
)。目标是完全阻止链接还是仅在实施代码中?否则,生成器本身可以进行链接,因此调用代码不必:
function* generator () {
const u = getUser(), c = u.then(userId => getUserComments(userId));
yield *[u,c];
}
实施例:
function getUser () {
return new Promise(function(resolve, reject) {
setTimeout(function() { resolve({id: 1, label: 'John'}); }, 200);
});
}
function getUserComments(userId) {
return new Promise(function(resolve, reject) {
setTimeout(function() {resolve({comments: 'comments', userId: userId}); }, 200);
});
}
function* generator () {
const u = getUser(), c = u.then(userId => getUserComments(userId));
yield *[u,c];
}
(async function(){
var g = generator();
var first = await g.next().value;
var second = await g.next().value;
console.log(first, second);
})();

对于呼叫代码,首先解决/等待哪个承诺并不重要。当然,如果等待后续步骤,必须完成以前步骤的链条。 e.g:
function getUser () {
return new Promise(function(resolve, reject) {
setTimeout(function() { resolve({id: 1, label: 'John'}); }, 200);
});
}
function getUserComments(userId) {
return new Promise(function(resolve, reject) {
setTimeout(function() {resolve({comments: 'comments', userId: userId}); }, 200);
});
}
function* generator () {
const u = getUser(), c = u.then(userId => getUserComments(userId));
yield *[u,c];
}
(async function(){
var g = generator();
var prom = g.next().value;
var second = await g.next().value;
console.log(await prom, second);
})();

答案 2 :(得分:0)
您可以使用参数调用next
并使用yield
获取。示例:
function* generator () {
var userId = yield getUser();
yield getUserComments(userId); // userId represents data from first request / first yield how should I pass it ?!
}
var g = generator();
var first = g.next();
var userId = getUserId(first);
var second = g.next(userId);
答案 3 :(得分:0)
我试图获得您需要的结果。如果没有.then()
,我就无法获得getUser()
function getUser () {
return new Promise(function(resolve, reject) {
return setTimeout(function() { resolve({id: 1, label: 'John'}); }, 200);
});
}
function getUserComments(userId) {
console.log(userId)
return new Promise(function(resolve, reject) {
return setTimeout(function() {resolve({comments: 'comments', userId: userId}); }, 200);
});
}
function* generator () {
var userId = yield getUser();
yield getUserComments(userId); // userId represents data from first request / first yield how should I pass it ?!
}
var g = generator();
(async function(){
var first = await g.next();
var userId = await first.value.then((res)=>{ return res.id });
g.next(userId);
})();