回调已被调用。但在那之前我从来没有打电话给回调。 async.parallel 中的错误? [复制]
Posted
技术标签:
【中文标题】回调已被调用。但在那之前我从来没有打电话给回调。 async.parallel 中的错误? [复制]【英文标题】:Callback was already called. But I never call callback before that. A bug in async.parallel? [duplicate] 【发布时间】:2017-12-16 14:21:56 【问题描述】:我在网上对这个问题做了很多研究,仍然无法知道问题的原因。
问题是,当我使用异步库中的并行函数时,出现错误:
Callback was already called.
这是我的代码:(我已在出现此错误的行上发表评论)
var sendNotificationAddToMyRememberNew = function(request, response, restaurant)
async.parallel(
notification_list: function (callback)
models.NotificationList.create(
alert_msg: "Restaurant " + restaurant.name + " remembered.",
payload: JSON.stringify(
restaurant_id: restaurant.id,
restaurant_name: restaurant.name,
restaurant_image: restaurant.image
),
type: constants.NOTIFICATION_TYPE.RESTAURANT_REMEMBERED,
platform_type: constants.MOBILE_PLATFORM_TYPE.ALL,
status: constants.NOTIFICATION_STATUS.SENT,
device_token: null,
device_arn: null,
schedule_time: moment.utc(),
customer_id: request.token.customer_id,
customer_email: request.token.email,
created_date: moment.utc(),
updated_date: moment.utc()
).then(function(notificationList)
callback(null, notificationList);
).catch(function(error)
callback(error);
);
,
badge_count: function(callback)
models.CustomerBadgeCount.findOrCreate(
where:
customer_id: request.token.customer_id
,
defaults:
badge_count: 1,
customer_id: request.token.customer_id,
created_date: moment.utc(),
updated_date: moment.utc()
).spread(function (badgeCount, created)
if(!created)
badgeCount.update(
badge_count: badgeCount.badge_count + 1,
updated_date: moment.utc()
,
fields:[
"badge_count",
"updated_date"
]
).then(function(badgeCount)
callback(null, badgeCount);
).catch(function (error)
callback(error); // Getting error of callback here
);
else
callback(null, badgeCount)
).catch(function (error)
callback(error);
);
,
devices: function(callback)
models.CustomerDeviceTokens.findAll(
where:
customer_email: request.token.email
).then(function(devices)
callback(null, devices);
).catch(function(error)
callback(error);
);
, function(error, results)
if(error)
Logger.logDbError(error,request);
return console.log(error);
//callback function
console.log("-------------------------------------------------------");
console.log("Notification List: " + JSON.stringify(results.notification_list, null, 4));
console.log("badge_count: " + JSON.stringify(results.badge_count, null, 4));
if(results.devices && result.devices.count > 0)
results.devices.forEach(function(device)
console.log("device_arn: " + device.device_arn);
, this);
);
【问题讨论】:
不要将 async.js 与 Promise 一起使用。普通的Promise.all
要容易得多。
@Bergi 这个问题不重复。我已经解决了这个问题。请看我的回答。
副本解释了difference between .then(…, …)
and .then(…).catch(…)
,这是导致callback
被调用两次的原因。
如果你觉得这个问题是重复的,那么请删除它。因为我不能删除它,因为这个问题已经有了答案。
@Bergi 对不起,我忘了在上面的评论中提到你的名字。请阅读。
【参考方案1】:
如果callback(null, badgeCount)
抛出错误,就会发生这种情况(如果最终回调由于某种原因抛出错误,就会发生这种情况)。
在这种情况下发生的情况是调用了 .catch
处理程序,在其中您再次调用 callback
,导致 “已调用” 消息。
为了防止这种情况(或者更确切地说,为了捕获这些错误),您不应使用 .catch
,而应使用 .then
的两个参数版本:
.then(function(badgeCount)
callback(null, badgeCount);
, function (error)
callback(error);
);
(对于代码中在 async
操作中使用 .then().catch()
的所有其他位置类似)
【讨论】:
好答案!!!!!!但我已经想通了。我会再发一个。感谢您的回答和您的时间。【参考方案2】:我在我的代码中使用了findOrCreate
sequelize 方法。 findOrCreate 的原始语法是:
model.SomeModelName.findOrCreate(
....
....
).spread(function(data, created)
).fail(function(err)
);
正如您在上面的代码中看到的那样,.spread()
后面应该跟着.fail()
,但在我的代码中,我使用了.spread()
,后面跟着.catch()
。
因此,两个块都已执行,因此 回调被调用了两次
【讨论】:
这可能是您在then
中获得异常的方式,但这不是实际问题。以上是关于回调已被调用。但在那之前我从来没有打电话给回调。 async.parallel 中的错误? [复制]的主要内容,如果未能解决你的问题,请参考以下文章