阻塞代码,直到第一个 forEach 循环完成以在 Node 中的另一个 forEach 循环中使用结果

Block code until first forEach loop finishes to use result in another forEach loop in Node

在 Whosebug 中也有类似的问题,但我找不到专门解决这个问题的问题。我在 Node 中有两个 forEach 循环和一个(这个:s.forEach((su) => { cw1.push(su.courseWorkId); }); ) 使用前一个的结果进行迭代,但它在第一个完成之前异步触发,所以它总是告诉我 "const s" (第一个 forEach 循环的结果)是空的。代码中的其他一切工作正常。任何帮助,将不胜感激。

const fs = require('fs');
const path = require('path');
const {google} = require('googleapis');
const keys = require("./file.json");
const sc = require('./jwt.js');
const scopes = sc.scopes;

const j2 = new google.auth.JWT(keys.client_email,null,keys.private_key,scopes,'me@email.com');

const classroom = google.classroom({version: 'v1', auth:j2});
const cl = classroom.courses;

let cl1 =  ['34809075556', '34800434710'];
let cw1 = [];

function getwi(){
  cl1.forEach((ids) => {                                                   
    cl.courseWork.list({courseId:ids}, (e,r) => {
      const s = r.data.courseWork;
      s.forEach((su) => { cw1.push(su.courseWorkId); });
    });
  });
}

getwi(); 

异步修改全局变量通常不是一个好主意。而是将异步任务包装到承诺中,然后将该承诺解析为您需要的值。

  const getCourseWork = courseId => new Promise((resolve, reject) => cl.courseWork.list({ courseId, }, (err, result) => err ? reject(err) : resolve(result)));

那么你可以得到如下结果:

  Promise.all( cl1.map(getCourseWork) )
     .then(result => console.log("The result is:", result.flat().map(it => it.id)))
     .catch(error => console.error("An error occured:", error));

这样一来,所有调用都是并行完成的,因此一个接一个调用速度更快。

Read on