JavaScript 减少 Promises 不按顺序返回
JavaScript reduce with Promises not returning sequentially
出于某种原因,所有功能都同时返回。
我想等待第一个函数解析然后调用 _done()
然后再调用第二个函数,然后调用 _done()
然后调用第三个函数然后再次调用 _done()
.
每次调用 _done()
时,我都想传递从上一个函数调用中解析出来的值。
工作演示在这里https://repl.it/MeHl/9
"use-strict"
function _test(actions){
return actions.reduce((chain, action) => {
const func = this[action.functionToCall](action.argumentToSend);
return chain.then(() => func()).then(val => console.log(val));
}, Promise.resolve().then(val => _done()));
}
function _one(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve();
}, 2000);
})
}
function _two(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve();
}, 2000);
})
}
function _three(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve();
}, 2000);
})
}
function _done(data){
console.log(data);
}
const arrayOfObjects = [
{ functionToCall: '_one', argumentToSend: 'Yay function one was called with this argument' },
{ functionToCall: '_two', argumentToSend: 'Yay function two was called with this argument' },
{ functionToCall: '_three', argumentToSend: 'Yay function three was called with this argument' },
];
_test(arrayOfObjects);
所以日志应该看起来像
Yay function one was called with this argument
resolvedFromOne
Yay function two was called with this argument
resolvedFromTwo
Yay function three was called with this argument
resolvedFromThree
这段代码产生了预期的输出
function _test(actions){
return actions.reduce((chain, action) => {
return chain.then(() => action.functionToCall(action.argumentToSend)).then(val => console.log(val));
}, Promise.resolve());
}
function _one(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve('resolvedFromOne');
}, 2000);
})
}
function _two(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve('resolvedFromTwo');
}, 2000);
})
}
function _three(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve('resolvedFromThree');
}, 2000);
})
}
// not required
function _done(data){
console.log(data);
}
const arrayOfObjects = [
{ functionToCall: _one, argumentToSend: 'Yay function one was called with this argument' },
{ functionToCall: _two, argumentToSend: 'Yay function two was called with this argument' },
{ functionToCall: _three, argumentToSend: 'Yay function three was called with this argument' },
];
_test(arrayOfObjects);
出于某种原因,所有功能都同时返回。
我想等待第一个函数解析然后调用 _done()
然后再调用第二个函数,然后调用 _done()
然后调用第三个函数然后再次调用 _done()
.
每次调用 _done()
时,我都想传递从上一个函数调用中解析出来的值。
工作演示在这里https://repl.it/MeHl/9
"use-strict"
function _test(actions){
return actions.reduce((chain, action) => {
const func = this[action.functionToCall](action.argumentToSend);
return chain.then(() => func()).then(val => console.log(val));
}, Promise.resolve().then(val => _done()));
}
function _one(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve();
}, 2000);
})
}
function _two(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve();
}, 2000);
})
}
function _three(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve();
}, 2000);
})
}
function _done(data){
console.log(data);
}
const arrayOfObjects = [
{ functionToCall: '_one', argumentToSend: 'Yay function one was called with this argument' },
{ functionToCall: '_two', argumentToSend: 'Yay function two was called with this argument' },
{ functionToCall: '_three', argumentToSend: 'Yay function three was called with this argument' },
];
_test(arrayOfObjects);
所以日志应该看起来像
Yay function one was called with this argument
resolvedFromOne
Yay function two was called with this argument
resolvedFromTwo
Yay function three was called with this argument
resolvedFromThree
这段代码产生了预期的输出
function _test(actions){
return actions.reduce((chain, action) => {
return chain.then(() => action.functionToCall(action.argumentToSend)).then(val => console.log(val));
}, Promise.resolve());
}
function _one(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve('resolvedFromOne');
}, 2000);
})
}
function _two(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve('resolvedFromTwo');
}, 2000);
})
}
function _three(data){
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log(data);
resolve('resolvedFromThree');
}, 2000);
})
}
// not required
function _done(data){
console.log(data);
}
const arrayOfObjects = [
{ functionToCall: _one, argumentToSend: 'Yay function one was called with this argument' },
{ functionToCall: _two, argumentToSend: 'Yay function two was called with this argument' },
{ functionToCall: _three, argumentToSend: 'Yay function three was called with this argument' },
];
_test(arrayOfObjects);