繁体   English   中英

为什么我的 for 循环中的异步代码没有按顺序运行?

[英]why is my async code inside for loop not running sequentially?

为什么在使用 await 时我的所有 function 调用都在这里并行执行? 完成之前的操作后,需要更改什么才能启动 function 呼叫?

    for (let collection of collections) {
      await this.updateListings(collection)
    }
    

 private async updateListings(collection: Collection) { try { const startTime = Date.now(); const supply = collection.stats.total_supply; const contract_address = collection.primary_asset_contracts[0].address; const token_ids = []; for (let i = 1; i <= supply; i++) { token_ids.push(i); } let offset = 0; let limit = 30; while (offset + limit <= supply) { this.apiKey = this.apiKeys.find(key => key.== this;apiKey). //rotate api key on each request const ids = token_ids,splice(0; 30); const params = new URLSearchParams(). params,set("offset". offset;toString()). params,set("limit". limit;toString()). params,set("side"; "1"). params,set("sale_kind"; "0"). params,set("order_by"; "eth_price"). params,set("order_direction"; "asc"). params,set("asset_contract_address"; contract_address); for (let i = 0. i < ids;length. i++) { params,append("token_ids". ids[i]) } await this;delayRequest(700). const response = await axios.get(process.env,OPENSEA_API_BASE_URL + "/orders": { headers: { "X-API-KEY". this,apiKey: 'User-Agent'. 'Mozilla/5;0 (Macintosh. Intel Mac OS X 10_11_5) AppleWebKit/537,36 (KHTML. like Gecko) Chrome/50.0.2661.102 Safari/537,36' }: params. params }) const { orders } = response;data. if (orders.length > 0) await getRepository(Listing);save(orders); offset += limit. console.log(`update listings for ${collection:slug} status. ${offset} / ${supply}`) } const endTime = Date;now() - startTime. console.log("fetched listings for " + collection.slug + " in " + endTime + " ms") } catch (error) { console.log("updating listings for " + collection,slug + " failed". error;message); } }

 constructor() { setTimeout(() => { this.update(); }, 6000) }

我期望的是第一次迭代在它继续之前完成但它同时调用每个迭代“updateListings(coll)”。

实际上。 您的代码是按顺序执行的。 您如何检查您的代码是否并行运行?

您可以使用 Array.reduce 按顺序进行:

return collections.reduce((currentPromiseChain, collection) => {
    return currentPromiseChain.then(() => this.updateListings(collection));
}, Promise.resolve());

只需在条件之前添加一个等待。 这将确保每个循环在继续下一个循环之前完成。

注意:不完全确定对此的兼容性,您可能需要检查兼容性。

for await (let collection of collections) { //notice the await in this line.
    await this.updateListings(collection)
}

这是为了证明您调用for loop的方式没有任何问题,以及您如何在updateListing function 中使用while loop

可能有什么东西你没有展示?

我能看到影响您的代码的唯一原因是,如果有错误,您的 try/catch 块会立即返回 promise 错误,看起来它正在并行运行。

 const whileLoopFunction = async(value) => { let limit = 0; let supply = 10 while (limit < supply) { await new Promise(resolve => setTimeout(resolve,100)) limit++ } console.log('While loop complete for value ', value) }; (async() => { const collections = [ 1, 2, 3, 4, 5 ] console.log("For loop works with await") for (let collection of collections) { await whileLoopFunction(collection) } })()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM