2017-01-28 14 views
0

Я ищу, чтобы создать массив функций для динамического вызова, который позже будет использоваться в вызове обещания Q.all ([]).Как вы нажимаете вызовы функций на массив без вызова их в Node JS для использования Q?

Например,

//data is previously generated 

var promiseArray = []; 
for (var i = 0; i < data.length; i++){  
    promiseArray.push(functionCall(data[i])) 
} 
Q.all(promiseArray).then(function(){ 
     //Do something 
}) 

Как бы я нажал на массив без вызова функции до утверждения Q.all? Я не хочу вызывать его в цикле for, поскольку он не будет ловить никаких ошибок, и я не могу обработать ответ дальше.

EDIT:

Так прояснить мою проблему (так как я не думаю, что я был так ясно, как я должен был), вот это решение для статической длины данных, скажем, 3;

//data is previously generated 
var data = [12432432,4324322392,433324323]; 

//Each function call can happen in parallel or series as its an external POST to an API 
//I'm not bothered about speed for this application (as its low throughput) and can wait a few seconds for each 
// response 
//FunctionCall returns a promise 

functionCall(data[0]).then(function(){ 
    //Log success/failure to mongo 
}); 
functionCall(data[1]).then(function(){ 
    //Log success/failure to mongo 
}); 
functionCall(data[2]).then(function(){ 
    //Log success/failure to mongo 
}); 

//OR 
functionCall(data[0]).then(function(){ 
    //Log success/failure to mongo 
    functionCall(data[1]).then(function(){ 
     //Log success/failure to mongo 
     functionCall(data[2]).then(function(){ 
      //Log success/failure to mongo 
     }); 
    }); 
}); 

Но я не буду знать длину данных до выполнения

+0

Uh, 'Q.all' действительно принимает множество обещаний, а не функций, поэтому вам нужно * их называть? – Bergi

+0

В основном я хочу иметь возможность создавать массив функций для вызова с помощью Q.all ([]), не вызывая их при добавлении их в массив. В противном случае я назову их, когда я их добавлю, а также позвоню им в Q.all ([]) – aaaidan

+0

Да, вы хотите сразу их вызвать. 'Q.all' не будет их называть. Я не понимаю, почему ваш первый фрагмент не будет работать. Ваш аргумент «* Я не хочу вызывать его в цикле for, поскольку он не будет ловить никаких ошибок, и я не могу обработать ответ дальше. *» Является ошибочным, вы можете легко ловить ошибки и обрабатывать результаты, затем'. – Bergi

ответ

1

Если я правильно понимаю, вы хотите вызвать functionCall для массива элементов, и есть Q.all решить сразу все обещания возвращаются по functionCall имеют завершены независимо от того, разрешают или отклоняют - если вы не заботитесь о результатах (как вы не видите в своем коде) просто обрабатывайте отклонение в обещании, которое вы нажимаете - т.е.

var promiseArray = []; 
for (var i = 0; i < data.length; i++) { 
    promiseArray.push(functionCall(data[i]).then(function(result) { 
     // log success 
     return logToMongoFunction(result); 
    }, function(error) { 
     // log failure 
     return logToMongoFunction(error); 
    }).catch(function(error) { 
     // catch and ignore any error thrown in either logToMongoFunction above 
     return; 
    })); 
} 
Q.all(promiseArray).then(function() { 
    //Do something 
}); 

Примечание: выше, может быть упрощено до

Q.all(data.map(function (item) { 
    return functionCall(item).then(function(result) { 
     // log success 
     return logToMongoFunction(result); 
    }, function(error) { 
     // log failure 
     return logToMongoFunction(error); 
    }).catch(function(error) { 
     // catch and ignore any error thrown in either logToMongoFunction above 
     return; 
    }); 
})).then(function() { 
    //Do something 
}); 

Отредактированного вопрос предполагает, что Вы можете выполнить действия в серии также - в серии было бы

data.reduce(function(promise, item) { 
    return promise.then(function() { 
     return functionCall(item).then(function(result) { 
      // log success 
      return logToMongoFunction(result); 
     }, function(error) { 
      // log failure 
      return logToMongoFunction(error); 
     }).catch(function(error) { 
      // catch and ignore any error thrown in either logToMongoFunction above 
      return; 
     }); 
    }); 
}, Promise.resolve()).then(function() { 
    // all done 
}); 

вместо Promise.resolve() вы можете использовать любой Q имеют как эквивалент, который создает разрешенное обещание

logToMongoFunction бы войти в Монго и должен вернуть обещание если вам нужно ждать, что закончить до их обработок следующий элемент данных. Если вам не нужно ждать завершения регистрации mongo, тогда нет необходимости в этой функции, чтобы вернуть обещание

+0

Что делать, если функцияCall получила некоторые операции с базой данных? например массив длиной 10000, этот код запускает все 10000 запросов вместе? я думаю, что должна быть очередь, и эти петли должны контролироваться –

+1

Что делать, если никто не изобрел штаны. Мы все будем носить платья. –

0

я рекомендуем использовать Promise.mapSeries или библиотеку асинхронной для этого, потому что его очень легко поймать ошибок. Еще одна вещь, связанная с использованием цикла for, кажется, не является хорошим подходом, если у вас есть вызовы базы данных в обратном вызове, поскольку это может привести к сбоям в вызовах в базе данных, а node.js может иметь проблемы с памятью или node.js не сможет развлекать другие потому что он будет занят занятием запросом в цикле for. поэтому всегда удобно запускать цикл поочередно или ограничивать количество параллельных исполнений за раз.

смотрите пример ниже

This will run Array serially one at a time when 1st one completes execution next will be called 

    async.eachOfSeries(data, function(dataInstance, key, next) { 
    functionCall(dataInstance).then(function(){ 
     next(); 
    }).catch(funtion(err){ 
     next(err); 
    }) 
    }, function() { 
     //iteration completed 
    }); 

ИЛИ

async.eachOfSeries(data, function(dataInstance, key, next) { 
    functionCall(dataInstance, function(err , result){ 
     if(err) 
      { 
      console.log(err); 
      next(err); 
      } 
      else 
      next(); 
    }); 
    }, function() { 
     //iteration completed 
    }); 
+1

Я неправильно понял проблему. Ваш ответ правильный –

+1

Здесь обещание и обратные вызовы смешаны. Было бы чище использовать любой из них. – Sangharsh

+0

@Sangharsh имеют смысл. позвольте мне уточнить мой ответ –