我对一个异步函数有点拘泥于此。
我要完成的是创建一个batchProcessing函数(batchGetSubs),它将循环访问一组文件,读取一个ID,然后发出一个API请求,等待一个响应(问题),然后用格式化的数据写入一个新文件。
问题--我尝试了异步和等待,以及推送承诺和尝试使用承诺.所有这些都是为了等待承诺的解决,但没有成功。当前的行为是,在API调用实际返回所有数据之前,我获取Promission.all部分中的所有console.logs。我引用了这些文章作为参考:
密码-
async function batchGetSubs(data, command) {
console.time('batchGetSubs')
iteration = 1;
let dataArray = []; promises = [];
// LOOP THROUGH FILES, THEN GET TENANTS BY SUB
for (i = iteration; i < totalIterations; i++) {
let msIds = await loopAndDump(iteration);
// LOOP THROUGH TENANTIDS AND GET SUBSCRIPTIONS
msIds.map(async item => {
let newRecord = await getSubsByTenantId(item);
promises.push(await newRecord);
});
}
Promise.all([promises]).then(() => { // FIXME: WHY IS THIS NOT WAITING FOR ALL RESPONSES?
console.log(p1SubscriptionArray),
console.timeEnd('batchGetSubs')
});
}
async function getSubsByTenantId(msTenantId) {
let newRecord; let subscriptionArray = [];
let bearerToken = p1BearerToken;
let totalSubs = 0;
const subIdConfig = {
method: 'get',
url: ``,
headers: { 'Authorization': bearerToken }
}
await delay();
await axios(subIdConfig)
.then(async res => {
console.log('AXIOS RESPONSE', res.data);
if (res.data.items) {
let subItems = res.data.items;
console.log('^^^^^^^^^^^^^^^^^^', res.data.items)
// LOOP THROUGH AND ADD TO SUBSCRIPTION ARRAY
subItems.map(async subscription => {
if (subscription.friendlyName) {
totalSubs++;
subscriptionArray.push(subscription.friendlyName);
}
});
newRecord = { "tenantId": msTenantId, "totalSubs": totalSubs, "subscriptionFriendlyName": subscriptionArray };
} else {
// NO SUBS
newRecord = { "tenantId": msTenantId, "totalSubs": totalSubs, "subscriptionFriendlyName": ['NONE'] };
let statusCode, errorMessage;
if (error && error.response === undefined) { // GETTING STATUS -4039 or -4077 INSTEAD OF 429 WHEN CHECKING SUBS. FORCE A RESEND.
if (error.errno && error.errno === -4039 || error.errno && error.errno === -4077) statusCode = 429; errorMessage = error.code;
} else {
statusCode = error.response.status;
errorMessage = error.response.statusText;
}
console.error('ERROR:: SUBIDCONFIG SECTION THROWING ERROR: ', statusCode, portal, errorMessage);
// SORT NON-200 CALLS BASED ON STATUS CODE
switch (statusCode) {
case 403:
status403.push('subs', newRecord);
break;
case 404:
status404.push('subs', newRecord);
erroring = true;
break;
case 429:
status429.push('subs', newRecord);
erroring = true;
break;
default:
statusOther.push('subs', newRecord)
erroring = true;
break;
}
}
})
.catch(err => {
newRecord = { "tenantId": msTenantId, "totalSubs": totalSubs, "subscriptionFriendlyName": ['NONE'] };
console.error('ERROR: REQUEST IN GETSUBSBYTENANTID(): ', err)
})
.then(res => {
console.log('DO WE HAVE ANY INFORMATION? ', newRecord);
p1SubscriptionArray.push(newRecord);
resolve();
});
}
你做一个等待然后在同一时间。你做一个承诺/然后或等待/异步
做
async function getSubsByTenantId(msTenantId) {
let newRecord; let subscriptionArray = [];
let bearerToken = p1BearerToken;
let totalSubs = 0;
const subIdConfig = {
method: 'get',
url: ``,
headers: { 'Authorization': bearerToken }
}
await delay();
const r = await axios(subIdConfig)
const reponse = r.data
console.log(response)
}
如果要尝试catch,请执行以下操作:
async function getSubsByTenantId(msTenantId) {
let newRecord; let subscriptionArray = [];
let bearerToken = p1BearerToken;
let totalSubs = 0;
const subIdConfig = {
method: 'get',
url: ``,
headers: { 'Authorization': bearerToken }
}
await delay();
let r
try {
r = await axios(subIdConfig)
} catch (error) {
console.log(error)
}
const reponse = r.data
console.log(response)
}
我只检查了第一个函数,您在其中提出了您的问题:
为什么这不是等待所有的回应呢?
有几个原因:
>
调用promise.all
时,promise
数组仍然为空。这是因为您只在await
之后执行push
,因此push
是异步发生的(稍后阅读)。
即使填充了promission
数组,它也不会包含promissions对象,而是解析值(即newrecord
值)
即使promission
是promissions的数组,您也没有将该数组正确传递给promission.all
:您将该数组包装在另一个数组中,然后该数组只有一个条目,而该条目不是promission,而是一个数组。
与您的问题无关,但:
>
请养成显式声明所有变量的习惯。您没有为迭代
、承诺
或i
执行此操作。
仅在使用返回值执行某些操作时使用.map
。对于纯迭代,请使用.foreach
或For
。在这种情况下,可以使用返回值扩展promission
数组。
如果您打算调用BatchGetSubs
并需要知道何时完成所有操作,那么请确保它返回一个有用的承诺:returnpromise.all()
以下是该函数的建议更正:
async function batchGetSubs(data, command) {
console.time('batchGetSubs')
let iteration = 1; // Declare!
let dataArray = [];
let promises = []; // declare
// declare i
for (let i = iteration; i < totalIterations; i++) {
let msIds = await loopAndDump(iteration);
// Use the return value of the map method. No need for async callback
promises.push(...msIds.map(item => {
// Get the promise, not the resolved value, as that will come too late:
return getSubsByTenantId(item);
}));
}
// promises is already an array; don't make it an array of arrays.
// And: return the resulting promise: it may be useful to the caller.
return Promise.all(promises).then(() => {
console.log(p1SubscriptionArray),
console.timeEnd('batchGetSubs')
});
}
问题内容: 我需要一个等待异步调用然后继续的循环。就像是: 我该怎么办?你有什么想法? 问题答案: 如果阻止脚本和浏览器,则无法在JavaScript中混合使用同步和异步。 您需要在此处采用完整的事件驱动方式,幸运的是我们可以将丑陋的东西藏起来。 编辑: 更新了代码。 这将为我们提供一个异步方法,您当然可以进一步修改它,例如使用一个检查循环条件的函数等。 现在进行测试: 并输出:
问题内容: 我是这个Node.js的新手..我对此回调有点困惑..在我的应用程序中,我在for循环内调用异步函数调用,我想我的问题是在得到异步调用响应之前, for循环被循环。 我的代码: 搜索功能代码: 我想在成功执行1个搜索功能后执行for循环,我想我必须使用async for loop。请指导我解决此问题。 问题答案: 我将您的代码示例简化为以下几行,以使您更容易理解该概念。 先前代码的问题
本文向大家介绍JavaScript 异步等待循环,包括了JavaScript 异步等待循环的使用技巧和注意事项,需要的朋友参考一下 示例 在循环中使用异步等待时,您可能会遇到其中一些问题。 如果您只是尝试在内部使用await forEach,则会抛出Unexpected token错误。 这是因为您错误地将箭头功能视为一个块。该await会在回调函数,这是不是上下文async。 解释器可以防止我们
问题内容: 这个问题已经在这里有了答案 : 循环内的JavaScript封闭-简单的实际示例 (44个答案) 2年前关闭。 我正在运行以下形式的事件循环: 我正在尝试显示一系列警报,显示从0到10的数字。问题是,当触发回调函数时,循环已经经历了几次迭代,并且显示了更高的值。有关如何解决此问题的任何建议? 问题答案: 在启动所有异步操作时,循环将立即运行到完成。当他们将来完成某个时间并调用其回调时,
本文向大家介绍JavaScript 异步操作和事件循环,包括了JavaScript 异步操作和事件循环的使用技巧和注意事项,需要的朋友参考一下 示例 常见的JavaScript编程环境中许多有趣的操作都是异步的。例如,在浏览器中,我们看到类似 在Node.js我们看到的东西像 这与事件循环如何配合? 这是如何工作的,当这些语句执行时,它们告诉主机环境(即Node.js分别为浏览器或运行时)关闭并可
问题内容: 事情是:我有一个页面,其中必须显示未确定数量的图像,这些页面是通过AJAX(在服务器端使用base64编码)一张一张地加载的。 问题是仅当获取所有图像时,才将图像(由renderImageData()函数构造)附加到所有DIV中(一起)。我的意思是,直到循环结束,才有可能进行任何DOM操作。 由于可能会有大量的图像,因此我需要一张一张地加载和显示图像,因此我无法将它们堆叠起来,直到将它