我使用的node.js模块有一个没有回调的方法。而不是它,有一个事件在该方法完成时触发。我希望解决一个承诺,使用该事件作为回调,确保我已成功完成该方法。
承诺上的array.lenght可以是X.所以,我需要'听'X次事件才能确保所有方法都已成功完成< - 这不是问题,我只是告诉你我知道这可能会发生
活动:
tf2.on('craftingComplete', function(recipe, itemsGained){
if(recipe == -1){
console.log('CRAFT FAILED')
}
else{
countOfCraft++;
console.log('Craft completed! Got a new Item #'+itemsGained);
}
})
无极:
const craftWepsByClass = function(array, heroClass){
return new Promise(function (resolve, reject){
if(array.length < 2){
console.log('Done crafting weps of '+heroClass);
return resolve();
}
else{
for (var i = 0; i < array.length; i+=2) {
tf2.craft([array[i].id, array[i+1].id]); // <--- this is the module method witouth callback
}
return resolve(); // <---- I want resolve this, when all tf2.craft() has been completed. I need 'hear' event many times as array.length
}
})
}
答案 0 :(得分:1)
如果事件的触发顺序与导致它们的相应craft()
调用的顺序相同,则可以使用队列:
var queue = []; // for the tf2 instance
function getNextTf2Event() {
return new Promise(resolve => {
queue.push(resolve);
});
}
tf2.on('craftingComplete', function(recipe, itemsGained) {
var resolve = queue.shift();
if (recipe == -1) {
resolve(Promise.reject(new Error('CRAFT FAILED')));
} else {
resolve(itemsGained);
}
});
function craftWepsByClass(array, heroClass) {
var promises = [];
for (var i = 1; i < array.length; i += 2) {
promises.push(getNextTf2Event().then(itemsGained => {
console.log('Craft completed! Got a new Item #'+itemsGained);
// return itemsGained;
}));
tf2.craft([array[i-1].id, array[i].id]);
}
return Promise.all(promises).then(allItemsGained => {
console.log('Done crafting weps of '+heroClass);
return …;
});
}
如果您对事件的顺序一无所知,并且可能有多个并发呼叫craftWepsByClass
,则无法避免全局计数器(即与tf2
链接的全局计数器实例)。缺点是例如在两个重叠的来电a = craftWepsByClass(…), b = craftWepsByClass()
中,a
承诺无法解决,直到完成第二个电话的制作。
var waiting = []; // for the tf2 instance
var runningCraftings = 0;
tf2.on('craftingComplete', function(recipe, itemsGained) {
if (--runningCraftings == 0) {
for (var resolve of waiting) {
resolve();
}
waiting.length = 0;
}
if (recipe == -1) {
console.log('CRAFT FAILED')
} else {
console.log('Craft completed! Got a new Item #'+itemsGained);
}
});
function craftWepsByClass(array, heroClass) {
for (var i = 1; i < array.length; i += 2) {
runningCraftings++;
tf2.craft([array[i-1].id, array[i].id]);
}
return (runningCraftings == 0
? Promise.resolve()
: new Promise(resolve => {
waiting.push(resolve);
})
).then(() => {
console.log('Done crafting weps of '+heroClass);
});
}
当然,在这两种解决方案中,您必须100%确定每次调用craft()
只会导致一个事件。
答案 1 :(得分:0)
首先让我们宣传制作:
function craft(elem){
//do whatever
return Promise((resolve,reject) =>
tf2.on('craftingComplete', (recipe,itemsGained) =>
if( recipe !== -1 ){
resolve(recipe, itemsGained);
}else{
reject("unsuccessful");
}
})
);
}
因此,为了制作倍数,我们将数组映射到promises并使用Promise.all:
Promise.all( array.map( craft ) )
.then(_=>"all done!")
答案 2 :(得分:0)
您可以查看event-as-promise
包。它将事件转换为Promise 持续,直到完成所有事件处理。
与async
/ await
结合使用时,您可以轻松地使用事件编写for循环或while循环。例如,我们希望处理data
事件,直到它返回null
。
const eventAsPromise = new EventAsPromise();
emitter.on('data', eventAsPromise.eventListener);
let done;
while (!done) {
const result = await eventAsPromise.upcoming();
// Some code to process the event result
process(result);
// Mark done when no more results
done = !result;
}
emitter.removeListener('data', eventAsPromise.eventListener);
如果你精通发电机功能,它可能看起来有点简单。
const eventAsPromise = new EventAsPromise();
emitter.on('data', eventAsPromise.eventListener);
for (let promise of eventAsPromise) {
const result = await promise;
// Some code to process the event result
process(result);
// Stop when no more results
if (!result) {
break;
}
}
emitter.removeListener('data', eventAsPromise.eventListener);
答案 3 :(得分:-1)
我需要检查事件'craftingComplete'是否像我一样多次触发 致电tf2.craft。没有任何可能的身份证或工艺失败。 我需要知道tf2.craft是否已经完成,只有为什么要检查 'craftingComplete'事件
鉴于我们知道Function unlock_conns()
Dim conn
For Each conn In ActiveWorkbook.Connections
Select Case conn.Type
Case xlConnectionTypeOLEDB
conn.OLEDBConnection.MaintainConnection = False
Case xlConnectionTypeODBC
conn.ODBCConnection.MaintainConnection = False
End Select
Next conn
End Function
圈内的i
for
将增加i += 2
i
小于.length
array
,我们可以在for
循环之前创建一个等于该数字的变量,并将i
与事件处理程序中的数字进行比较
const craftWepsByClass = function(array, heroClass) {
return new Promise(function(resolve, reject) {
var countCraft = 0;
var j = 0;
var n = 0;
for (; n < array.length; n += 2);
tf2.on('craftingComplete', function(recipe, itemsGained) {
if (recipe == -1) {
console.log('CRAFT FAILED')
} else {
countOfCraft++;
console.log('Craft completed! Got a new Item #' + itemsGained);
if (j === n) {
resolve(["complete", craftCount])
}
}
})
if (array.length < 2) {
console.log('Done crafting weps of ' + heroClass);
return resolve();
} else {
try {
for (var i = 0; i < array.length; i += 2, j += 2) {
tf2.craft([array[i].id, array[i + 1].id]);
}
} catch (err) {
console.error("catch", err);
throw err
}
}
})
}
craftWepsByClass(array, heroClass)
.then(function(data) {
console.log(data[0], data[1])
})
.catch(function(err) {
console.error(".catch", err)
})