在下面的示例代码中我可以同时运行多功能
Promise.all([sendMoneyToRequestedUser(_data), saveTransferMoneyTransaction(_data)])
.then(function (results) {
log.info("OOOOOOOOOOOOOo");
}).catch(function (error) {
log.info(error)
});
但是我想为它们创建简单的队列,例如,我可以用Promise
用这个解决方案实现吗?我有3个函数check
,send
和post
,我想要连续运行并将每个步骤的结果传递给另一个。
第1步,check()
函数,第2步,send()
函数,然后在完成它们后执行函数,例如post()
对于这个实现我需要获得每个步骤的结果,例如从第1步得到结果,如果它返回true然后在第2步我需要使用结果第1步,
是这个实现的async.parallel
解决方案吗?或Promise
可以这样做
答案 0 :(得分:2)
更新:问题并不是很明确,所提供的内容以及所需的内容。从评论中,我得到以下内容:
提供了FROM wordpress:fpm
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update &&\
apt-get install -y unzip &&\
rm -rf /var/cache/apt/*
ENV PLUGIN_URL https://downloads.wordpress.org/plugin
ENV PIWIK_PLUGIN_VERSION 1.0.9
RUN curl -o /tmp/wp-piwik.${PIWIK_PLUGIN_VERSION}.zip ${PLUGIN_URL}/wp-piwik.${PIWIK_PLUGIN_VERSION}.zip &&\
unzip /tmp/wp-piwik.${PIWIK_PLUGIN_VERSION}.zip -d /tmp &&\
chown www-data:www-data /tmp/wp-piwik &&\
mv /tmp/wp-piwik /usr/src/wordpress/wp-content/plugins/&&\
find /usr/src/wordpress/wp-content/plugins/wp-piwik -type d -exec chmod 755 {} + &&\
find /usr/src/wordpress/wp-content/plugins/wp-piwik -type d -exec chmod 633 {} + &&\
ls -l /usr/src/wordpress/wp-content/plugins/
,check
和send
的三个函数,希望它们能够串行运行。
假设提到的post
,check
和send
都返回Promise,例如:
post
然后您可以按如下方式构建队列:
function check() {
return new Promise(function (resolve, reject) {
// Do some stuff and save them in a var 'results'
var results = ...;
resolve(results);
});
}
在每个级别调用该函数,并从上一级别解析该值。
答案 1 :(得分:1)
我认为您正在寻找的是async.series
。以顺序顺序依次运行一系列函数,并将结果数组传递给前一函数的回调。
示例强>
var async = require('async');
async.series([
function(callback) {
//Do a bunch of relevant stuff
callback(null, 'First function');
},
function(callback) {
//Do some more relevant stuff
callback(null, 'Second function');
}
],
function(err, results) {
console.log(results); //Logs ['First function', 'Second function']
});
答案 2 :(得分:1)
在尝试使用各种模块时遇到了问题,最后我写了我可以想到的最简单的实现。
看看我写的这个简单的类(普通JS):
class Queue {
constructor(maxSimultaneously = 1) {
this.maxSimultaneously = maxSimultaneously;
this.__active = 0;
this.__queue = [];
}
/** @param { () => Promise<T> } func
* @template T
* @returns {Promise<T>}
*/
async enqueue(func) {
if(++this.__active > this.maxSimultaneously) {
await new Promise(resolve => this.__queue.push(resolve));
}
try {
return await func();
} catch(err) {
throw err;
} finally {
this.__active--;
if(this.__queue.length) {
this.__queue.shift()();
}
}
}
}
像这样使用它:
让我们说你有这个异步功能:
const printNumber = async (n) => {
await new Promise(res => setTimeout(res, 2000)); // wait 2 sec
console.log(n);
}
所以,而不是:
await printNumber(1);
await printNumber(2);
await printNumber(3);
await printNumber(4);
使用:
const q = new Queue();
q.enqueue(() => printNumber(1));
q.enqueue(() => printNumber(2));
q.enqueue(() => printNumber(3));
q.enqueue(() => printNumber(4));
每个功能都将在其他功能完成后执行。
输出:
1 // after 2 sec
2 // after 4 sec
3 // after 6 sec
4 // after 8 sec
或者您可以限制队列同时运行最多一些功能:
const q = new Queue(3);
q.enqueue(() => printNumber(1));
q.enqueue(() => printNumber(2));
q.enqueue(() => printNumber(3));
q.enqueue(() => printNumber(4));
输出:
1 // after 2 sec
2 // after 2 sec
3 // after 2 sec
4 // after 4 sec
也,enqueue方法将从您的诺言中返回/抛出原始数据!
让我们假设您编写了一个用于上传文件的API,并且您希望同时限制最多上传5次。您希望一切保持不变,而不改变流程。这是您可以执行的操作:
async function upload(data) {
// upload...
if(something) {
return 200;
} else {
throw 400;
}
}
所以,不要这样做:
async function work(data) {
// do something...
return await upload(data);
}
执行此操作:
const q = new Queue(5); // up to 5 at the same time
async function work(data) {
// do something...
return await q.enqueue(() => upload(data));
}
class Queue {
constructor(maxSimultaneously = 1) {
this.maxSimultaneously = maxSimultaneously;
this.__active = 0;
this.__queue = [];
}
/** @param { () => Promise<T> } func
* @template T
* @returns {Promise<T>}
*/
async enqueue(func) {
if(++this.__active > this.maxSimultaneously) {
await new Promise(resolve => this.__queue.push(resolve));
}
try {
return await func();
} catch(err) {
throw err;
} finally {
this.__active--;
if(this.__queue.length) {
this.__queue.shift()();
}
}
}
}
const printNumber = async (n) => {
await new Promise(res => setTimeout(res, 2000)); // wait 2 sec
console.log(n);
}
async function start() {
console.log('starting...');
const q = new Queue();
q.enqueue(() => printNumber(1));
q.enqueue(() => printNumber(2));
q.enqueue(() => printNumber(3));
q.enqueue(() => printNumber(4));
}
Click this to run 1 log per 2 sec: <button onclick="start();">Start</button>
class Queue {
constructor(maxSimultaneously = 1) {
this.maxSimultaneously = maxSimultaneously;
this.__active = 0;
this.__queue = [];
}
/** @param { () => Promise<T> } func
* @template T
* @returns {Promise<T>}
*/
async enqueue(func) {
if(++this.__active > this.maxSimultaneously) {
await new Promise(resolve => this.__queue.push(resolve));
}
try {
return await func();
} catch(err) {
throw err;
} finally {
this.__active--;
if(this.__queue.length) {
this.__queue.shift()();
}
}
}
}
const printNumber = async (n) => {
await new Promise(res => setTimeout(res, 2000)); // wait 2 sec
console.log(n);
}
async function start() {
console.log('starting...');
const q = new Queue(3);
q.enqueue(() => printNumber(1));
q.enqueue(() => printNumber(2));
q.enqueue(() => printNumber(3));
q.enqueue(() => printNumber(4));
}
Click this to run up to 3 logs every 2 sec: <button onclick="start();">Start</button>