【发布时间】:2017-09-27 04:56:52
【问题描述】:
我在 Node 异步操作(来自 PHP 背景)方面遇到了困难。我知道你可以嵌套回调,但这很快就会失控。
这是一个我想同步解决的基本示例(我知道对于这个示例异步解决可能很简单,但我需要知道如何同步解决更复杂的项目)。
这是一个快速应用程序,我正在尝试计算优惠券的使用次数:
var express = require('express');
var wrap = require('co-express');
app.post('/grab-valid-coupons', wrap(function* (req, res) {
var validCoupons = [];
console.log('grabbing coupons');
var coupons = yield db.collection('Coupons').find({}).toArray();
coupons.forEach(wrap(function* (coupon, index) {
console.log(coupon.code, 'CODE');
var couponUse = 0;
couponUse += yield db.collection('Rentals').find({coupon: coupon.code}).count();
couponUse += yield db.collection('Orders').find({coupon: coupon.code}).count();
console.log(couponUse);
if(couponUse < coupon.uses) {
validCoupons.push(coupon);
}
}));
res.json(validCoupons);
}));
第一个收益正在工作,但是我尝试获取所有内容的计数的部分导致整个服务器挂起。有什么想法吗?
【问题讨论】:
-
问题在于
wrap允许以同步方式编写其中的代码wrap本身是异步的。更糟糕的是,它是异步的,没有返回任何承诺或接受任何回调,因此它只能用作最顶层的异步函数。使用 wrap inside wrap 不起作用。在 forEach 中使用 wrap 也不起作用。它只适用于像 post 这样的快速中间件回调。 -
@slebetman 好的,那么在这种情况下,生成器似乎不是可行的方法
-
这就是使用替代异步处理程序的问题,例如基于生成器的 trampoline(这是 co* 库所做的)或 async-await 或 promises:你真的,真的需要先了解异步代码和回调,然后才能了解舒适地使用它们以了解正在发生的事情。否则,您将无法开始修复代码中的错误。如果您真的是 PHP 程序员,那么我无法相信您不熟悉异步代码。我敢肯定你以前用过
.onclick和.onload。这就是异步的意义所在。 -
给
Promise一些时间。 -
既然没有人提到它:你不能把异步代码变成同步的。正如@slebetman 所写:您确实需要首先完全理解异步代码和回调。然后处理承诺。只有这样你才能冒险使用生成器和异步等待。