Javascript 递归调用承诺函数
我试图递归调用一个promise函数 下面的调用服务.getSentenceFragment()从一个句子中最多返回5个字母,即“helloworld”中的“hello”。将nextToken值作为参数提供给调用将返回序列中的下5个字母。i、 e.“世界”。以下代码返回“hellohelloworldworld”,并且不登录到控制台Javascript 递归调用承诺函数,javascript,recursion,promise,Javascript,Recursion,Promise,我试图递归调用一个promise函数 下面的调用服务.getSentenceFragment()从一个句子中最多返回5个字母,即“helloworld”中的“hello”。将nextToken值作为参数提供给调用将返回序列中的下5个字母。i、 e.“世界”。以下代码返回“hellohelloworldworld”,并且不登录到控制台 var sentence = ''; getSentence().then(function (data)) { console.log(sentence)
var sentence = '';
getSentence().then(function (data)) {
console.log(sentence);
});
function getSentence(nextToken) {
return new Promise((resolve, reject) => {
getSentenceFragment(nextToken).then(function(data) {
sentence += data.fragment;
if (data.nextToken != null && data.nextToken != 'undefined') {
getSentence(data.NextToken);
} else {
resolve();
}
}).catch(function (reason) {
reject(reason);
});
});
}
function getSentenceFragment(nextToken) {
return new Promise((resolve, reject) => {
service.getSentenceFragment({ NextToken: nextToken }, function (error, data) {
if (data) {
if (data.length !== 0) {
resolve(data);
}
} else {
reject(error);
}
});
});
}
因为当你这样做的时候:
getSentence(data.NextToken);
一个新的承诺链启动,而当前的承诺链将永远挂起。我们可以这样做:
getSentence(data.NextToken).then(resolve, reject)
。。。但实际上你可以把整个事情美化成:
async function getSentence(){
let sentence = "", token;
do {
const partial = await getSentenceFragment(token);
sentence += partial.fragment;
token = partial.NextToken;
} while(token)
return sentence;
}
注意getSentenceFragment
中的这个陷阱-如果data
是真实的,但是data.length
是0,那么您的代码将进入死胡同,承诺将超时
// from your original getSentenceFragment...
if (data) {
if (data.length !== 0) {
resolve(data);
}
/* implicit else: dead end */
// else { return undefined }
} else {
reject(error);
}
相反,使用&&
组合两个if
语句,现在我们的承诺将始终解决或拒绝
// all fixed!
if (data && data.length > 0)
resolve(data);
else
reject(error);
因为当你这样做的时候:
getSentence(data.NextToken);
一个新的承诺链启动,而当前的承诺链将永远挂起。我们可以这样做:
getSentence(data.NextToken).then(resolve, reject)
。。。但实际上你可以把整个事情美化成:
async function getSentence(){
let sentence = "", token;
do {
const partial = await getSentenceFragment(token);
sentence += partial.fragment;
token = partial.NextToken;
} while(token)
return sentence;
}
注意getSentenceFragment
中的这个陷阱-如果data
是真实的,但是data.length
是0,那么您的代码将进入死胡同,承诺将超时
// from your original getSentenceFragment...
if (data) {
if (data.length !== 0) {
resolve(data);
}
/* implicit else: dead end */
// else { return undefined }
} else {
reject(error);
}
相反,使用&&
组合两个if
语句,现在我们的承诺将始终解决或拒绝
// all fixed!
if (data && data.length > 0)
resolve(data);
else
reject(error);
你可以递归地这样称呼承诺:
getSentence("what is your first token?")
.then(function (data) {
console.log(data);
});
function getSentence(nextToken) {
const recur = (nextToken,total) => //no return because there is no {} block so auto returns
getSentenceFragment(nextToken)
.then(
data => {
if (data.nextToken != null && data.nextToken != 'undefined') {
return recur(data.NextToken,total + data.fragment);
} else {
return total + data.fragment;
}
});//no catch, just let it go to the caller
return recur(nextToken,"");
}
function getSentenceFragment(nextToken) {
return new Promise((resolve, reject) => {
service.getSentenceFragment({ NextToken: nextToken }, function (error, data) {
if (data) {
if (data.length !== 0) {
resolve(data);
}
} else {
reject(error);
}
});
});
}
你可以递归地这样称呼承诺:
getSentence("what is your first token?")
.then(function (data) {
console.log(data);
});
function getSentence(nextToken) {
const recur = (nextToken,total) => //no return because there is no {} block so auto returns
getSentenceFragment(nextToken)
.then(
data => {
if (data.nextToken != null && data.nextToken != 'undefined') {
return recur(data.NextToken,total + data.fragment);
} else {
return total + data.fragment;
}
});//no catch, just let it go to the caller
return recur(nextToken,"");
}
function getSentenceFragment(nextToken) {
return new Promise((resolve, reject) => {
service.getSentenceFragment({ NextToken: nextToken }, function (error, data) {
if (data) {
if (data.length !== 0) {
resolve(data);
}
} else {
reject(error);
}
});
});
}
哦,不,承诺构造函数反模式。听起来你想研究一下使用
yield
关键字和generator
。这篇文章应该很有帮助:另外,为了修复您所拥有的,我非常确定您只需要替换get句子(data.NextToken)代码>与解析(get句子(data.NextToken))代码>哦,不。承诺构造函数反模式。听起来你想研究一下使用yield
关键字和generator
。这篇文章应该很有帮助:另外,为了修复您所拥有的,我非常确定您只需要替换get句子(data.NextToken)代码>与解析(get句子(data.NextToken))代码>