在一个简单的JS程序中,我需要让asyncOperation2和asyncOperation3与asyncOperation1一起顺序执行。意思是我需要做以下事情:
1) order of execution as 1,2,3 or 2,3,1
2) then after step 1. I need to preform an operation on the result of 1,2,3
这是我到目前为止所拥有的(这将在Node中运行)。但是我不能像上面描述的那样让操作顺序发生。
const App = {
total: 0,
init: function () {
// I want to run all 3 operations. (with 2 and 3 happening sequentially)
Promise.all([App.asyncOperation1(1000), App.combine2and3()])
.then((total) => {
// then I want to use the result of all 3 operations
console.log(`total from top: ${total}`);
})
},
asyncOperation1: function (time) {
return new Promise(function (resolve, reject) {
var intervalID = setTimeout(function () {
resolve(time);
}, time);
});
},
asyncOperation2: async function (time) {
setTimeout(function () {
return time;
}, time);
},
asyncOperation3: async function (time) {
setTimeout(function () {
return time;
}, time);
},
combine2and3: async function () {
var value2 = await App.asyncOperation2(2000);
var value3 = await App.asyncOperation3(1000);
console.log(`value2: ${value2}`)
console.log(`value3: ${value3}`)
console.log(`summed total ${value2 + value3}`);
return value2 + value3;
},
};
App.init();
实际结果:
value2: undefined
value3: undefined
summed total NaN
total from top: 1000,NaN
期望的结果:
value2: 2000
value3: 1000
summed total 3000
total from top: 1000,3000
答案 0 :(得分:2)
asyncOperation2
和asyncOperation3
应解决承诺。 (你在combine2and2
中做了什么)。
PS。从setTimeout
返回一些值是错误的。你不能这样做
将它们包裹在Promise
中并解析您想要从中返回的值。
像
这样的东西
const App = {
total: 0,
init: function () {
// I want to run all 3 operations. (with 2 and 3 happening sequentially)
Promise.all([App.asyncOperation1(1000), App.combine2and3()])
.then((total) => {
// then I want to use the result of all 3 operations
console.log(`total from top: ${total}`);
})
},
asyncOperation1: function (time) {
return new Promise(function (resolve, reject) {
var intervalID = setTimeout(function () {
resolve(time);
}, time);
});
},
asyncOperation2: function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(time);
}, time);
});
},
asyncOperation3: function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(time);
}, time);
})
},
combine2and3: async function () {
var value2 = await App.asyncOperation2(2000);
var value3 = await App.asyncOperation3(1000);
console.log(`value2: ${value2}`)
console.log(`value3: ${value3}`)
console.log(`summed total ${value2 + value3}`);
return value2 + value3;
},
};
App.init();
答案 1 :(得分:2)
问题是asyncOperation2()
和asyncOperation3()
会返回一个承诺
(因为他们的async
声明)没有解析的值(因此它是undefined
),因为这些函数没有自己的返回值。
asyncOperation2: async function (time) {
setTimeout(function () {
return time; // this just returns back into the timer sub-system
}, time);
// there is no return value for your function here
// thus the promise the async function returns has an undefined resolved value
},
从setTimeout()
内部返回不是函数的返回值。这只是返回到函数本身返回很久之后发生的计时器内部。请记住,setTimeout()
是非阻止的。它安排一些代码在将来的某个时间运行,然后立即返回,然后你的函数完成并返回(在setTimeout()
被触发之前)。所以,稍后一段时间后,你的setTimeout()
会触发并从该回调中返回一个值,该值只会返回到计时器子系统,而不是任何代码或任何承诺。
将这两个功能更改为:
function delay(t, v) {
return new Promise(resolve => {
setTimeout(resolve.bind(null, v));
}, t);
}
asyncOperation2: function (time) {
return delay(time, time);
},
asyncOperation3: function (time) {
return delay(time, time);
},
现在您有了返回使用所需值解析的promise的函数。注意,它们不需要声明为async
,因为你没有在函数内部使用await
而你已经创建了自己的返回承诺。
答案 2 :(得分:0)
当回调函数中的return time
传递给setTimeout
时,只返回回调函数,而不是外部函数。您必须将setTimeout
调用包含在承诺中,例如在asyncOperation1
中。您还可以创建辅助函数以避免重复。
const wait = time => new Promise(
resolve => setTimeout(() => resolve(time), time)
);
const App = {
total: 0,
init: function () {
// I want to run all 3 operations. (with 2 and 3 happening sequentially)
Promise.all([App.asyncOperation1(1000), App.combine2and3()])
.then((total) => {
// then I want to use the result of all 3 operations
console.log(`total from top: ${total}`);
})
},
asyncOperation1: wait,
asyncOperation2: wait,
asyncOperation3: wait,
combine2and3: async function () {
var value2 = await App.asyncOperation2(2000);
var value3 = await App.asyncOperation3(1000);
console.log(`value2: ${value2}`)
console.log(`value3: ${value3}`)
console.log(`summed total ${value2 + value3}`);
return value2 + value3;
},
};
App.init();