Javascript Promise解决混乱

时间:2018-09-10 07:01:01

标签: javascript typescript async-await

private runMiddlewares(route: Route | ExceptionRoute, request: HttpRequest, response: HttpResponse): Promise<any> {
    return new Promise((resolve, reject) => {
        try {
            route.middlewares.forEach(async (middleware: IMiddleware) => {
                console.log('begin run middleware');
                await middleware.process(request, response);
                console.log('resolve run middleware');
                console.log(request.body);
            });
            console.log('resolve all runMiddlewares');
            resolve();
        } catch (e) {
            reject(e);
        }
    });
}

我已经编写了此函数runMiddlewares,当所有middleware.process()都已解析后,该函数理想情况下为resolve()。我正在使用打字稿await功能,但似乎无法正常工作。 我希望route.middlewares.forEach(

内会发生这种情况
  • “开始运行中间件”
  • 然后等待解决
  • “解决运行中间件”

forEach循环中的所有中间件都将继续执行此操作,然后在列表全部完成后,才打印“ resolve all runMiddlewares”,最后private runMiddlewares( ... )应该被解决。

但是相反,forEach现在得到了立即解决,从而阻止了所有中间件的完成。

应如何处理?我认为await会在forEach循环内处理它,直到resolve中的runMiddlewares才会被调用。 我在这里想念什么?

2 个答案:

答案 0 :(得分:3)

您可以使用map从中间件创建一个承诺数组。可以将此承诺数组传递给Promise.all,它会在解决数组的每个单个承诺时解决。

await Promise.all(route.middlewares.map((middleware: IMiddleware) => {
            console.log('begin run middleware');
            const promise = middleware.process(request, response);
            console.log('resolve run middleware');
            console.log(request.body);
            return promise
        });

或更紧凑:

runMiddlewares(...) {
  return Promise.all(
    route.middlewares.map((middleware: IMiddleware) => {
      return middleware.process(request, response))
    })
  )
}

答案 1 :(得分:0)

因此,按照推荐(https://cn.eslint.org/docs/3.0.0/rules/no-await-in-loop),我将其编写如下

private runMiddlewares(route: Route | ExceptionRoute, request: HttpRequest, response: HttpResponse): Promise<any> {
    return new Promise(async (resolve, reject) => {
        try {
            const middlewarePromiseArry: any[] = [];
            route.middlewares.forEach((middleware: IMiddleware) => {
                console.log('begin run middleware');
                middlewarePromiseArry.push(middleware.process(request, response));
                // removed the use of await inside of forEach loop following this link: https://cn.eslint.org/docs/3.0.0/rules/no-await-in-loop
                // await middleware.process(request, response);
                // console.log('resolve run middleware');
                // console.log(request.body);
            });

            await Promise.all(middlewarePromiseArry);
            console.log('resolve all runMiddlewares');
            resolve();
        } catch (e) {
            reject(e);
        }
    });
}

我很高兴接受进一步的答案和建议/改进:)