【发布时间】:2019-07-16 04:56:34
【问题描述】:
我试图从另一个异步函数运行的循环中调用一个异步函数。这些函数调用 API,我使用 request-promise 和 nodeJS。
functions.js 文件
const rp = require("request-promise");
// function (1)
async email_views: emailId => {
let data = {};
await rp({
url: 'myapiurl',
qs: { accessToken: 'xyz', emailID: emailId },
method: 'GET'
})
.then( body => { data = JSON.parse(body) })
.catch( error => { console.log(error} );
return data;
};
上面的 JSON 看起来像这样:
...
data:{
records: [
{
...
contactID: 123456,
...
},
{
...
contactID: 456789,
...
}
]
}
...
我正在运行一个循环来获取单个记录,其中我得到一个与每个记录相关联的contactID。
// function#2 (also in functions.js file)
async contact_detail: contactId => {
let data = {};
await rp({
url: 'myapiurl2',
qs: { accessToken: 'xyz', contactID: contactId },
method: 'GET'
})
.then( body => { data = JSON.parse(body) })
.catch( error => { console.log(error} );
return data;
};
上述函数将contactId 作为参数,并通过调用另一个API 端点获取该联系人的详细信息。
这两个函数在单独调用时都能正常工作。但我试图在这样的循环中做到这一点:
...
const result = await email_views(99999); // function#1
const records = result.data.records;
...
let names = "";
for( let i=0; i<records.length; i++) {
...
const cId = records[i].contactID;
const contact = await contact_detail(cId); // function#2
names += contact.data.firstName + " " + contact.data.lastName + " ";
...
}
console.log(names);
...
问题是我只从上面的代码块中得到第一个 contact,即即使我有来自 function#1 的 20 条记录,在我调用 contact_detail 时的循环中(函数#2) 对于每个contactID (cId),我会获得一次联系方式,即仅针对第一个cId。休息我什么都得不到!
使用nodeJs 实现此目的的正确方法是什么?
更新:
const { App } = require("jovo-framework");
const { Alexa } = require("jovo-platform-alexa");
const { GoogleAssistant } = require("jovo-platform-googleassistant");
const { JovoDebugger } = require("jovo-plugin-debugger");
const { FileDb } = require("jovo-db-filedb");
const custom = require("./functions");
const menuop = require("./menu");
const stateus = require("./stateus");
const alexaSpeeches = require("./default_speech");
const app = new App();
app.use(new Alexa(), new GoogleAssistant(), new JovoDebugger(), new FileDb());
let sp = "";
async EmailViewsByContactIntent() {
try {
const viewEmailId =
this.$session.$data.viewEmailIdSessionKey != null
? this.$session.$data.viewEmailIdSessionKey
: this.$inputs.view_email_Id_Number.value;
let pageIndex =
this.$session.$data.viewEmailPageIndex != null
? this.$session.$data.viewEmailPageIndex
: 1;
const result = await custom.email_views_by_emailId(
viewEmailId,
pageIndex
);
const records = result.data.records;
if (records.length > 0) {
const totalRecords = result.data.paging.totalRecords;
this.$session.$data.viewEmailTotalPages = totalRecords;
sp = `i have found a total of ${totalRecords} following view records. `;
if (totalRecords > 5) {
sp += `i will tell you 5 records at a time. for next 5 records, please say, next. `;
this.$session.$data.viewEmailIdSessionKey = this.$inputs.view_email_Id_Number.value;
this.$session.$data.viewEmailPageIndex++;
}
for (let i = 0; i < records.length; i++) {
const r = records[i];
/* Here I want to pass r.contactID as contactId in the function contact_detail like this: */
const contact = await custom.contact_detail(r.contactID);
const contact_name = contact.data.firstName + " " + contact.data.lastName;
/* The above two lines of code fetch contact_name for the first r.contactID and for the rest I get an empty string only. */
const formatted_date = r.date.split(" ")[0];
sp += `contact ID ${spellOut_speech_builder(
r.contactID
)} had viewed on ${formatted_date} from IP address ${
r.ipAddress
}. name of contact is, ${contact_name}. `;
}
if (totalRecords > 5) {
sp += ` please say, next, for next 5 records. `;
}
} else {
sp = ``;
}
this.ask(sp);
} catch (e) {
this.tell(e);
}
}
我正在使用JOVO 框架和nodeJS 构建一个alexa 技能。
更新 #2
作为测试,我只返回了contactId,我将其传递给contact_detail 函数,并且在我的第一个UPDATE 下,我将正确的值返回到上述代码。
async contact_detail: contactId => {
return contactId;
}
似乎即使在获得正确的值之后,该函数还是无法执行。但是,当我从另一个地方调用它时,相同的 contact_detail 函数可以正常工作。只有在循环中不起作用。
可能是什么原因? 我一定错过了什么,但不知道是什么!
【问题讨论】:
-
我不确定返回数据的方式。我可能是错的,这是完全合法的。看到 done 函数和其他地方(即 return 语句)之间的逻辑分裂,我只是感到紧张。我倾向于在 try catch 块中等待数据,或者可能只是返回承诺并执行 Promise.all() - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
您的
contact_detail()函数调用没有显示任何实际使用您传递给它的参数的代码。如果它没有使用传入的contact_id,那么无论你通过什么,它总是会给你相同的结果。除此之外,我们需要查看for循环中的其余代码,以了解哪里出了问题。 -
@jfriend00 我不确定您到底需要什么。根据您所说的我的理解,我已经更新了代码块和循环部分。请让我知道这是否有帮助。谢谢!
-
contactID和contactId有没有可能在某个地方混在一起?查询字符串中应该包含什么?我只是想看看为什么contact_detail(cId);每次都会让你第一次联系。您的查询似乎有问题。 -
很抱歉给您带来了困惑。它不是每次都第一次接触。我得到的是第一次说 Andrew 的联系人姓名,然后对于其余记录 (
contactIDs) 我得到的是空值。
标签: node.js async-await request-promise