我已经在StackOverflow上发布了有关此主题的问题。按照建议,我试图简化我的问题。
尽管我已经阅读并尝试了不同的方法,但我不知道如何使用Promises及其新的精巧版本使用async / await进行同步代码。
在这里,我链接了有关该主题的一些很好的文档,以防将来对人们有所帮助。基本上,Promise是对回调地狱的一种回答,是一种使代码在其他代码执行后执行的方法,这使事情同步发生,因为JavaScript(因此Node.js)本质上是异步的。 Async / await建立在Promises之上,可以简化代码。
understanding JavaScript Promises
modern JavaScript with async/await
Async/await explained with examples
why moving from Promises to async/await
尽管我似乎了解这个概念,但是我无法解释我获得的结果。为了更好地理解,下面是一个使用node.js -v v8.10.0
/* This file try to use Promises and async/await to run code synchronously */
/* declaration of some Promisified functions */
const doSomethingAsync = () => { // direct declaration using new Promise and Promise.resolve()
return new Promise(resolve => { // This is just a promise, necesiry to wait for it
setTimeout(() => resolve('I want to be first'), 3000);
});
};
const test1 = async () => { // indirect Promise declaration usind async
return setTimeout(() => console.log("test1, I want to be executed first"), 3000); // async => the function returns a promise hence return a resolve,
}; // we should use await to wait for the Promise.resolve()
/* create intermediate calling functions making code synchronous to use console.log() properly */
const doSomething = async () => {
console.log( await doSomethingAsync());
};
const callTest = async () => {
console.log("hope to be executed before test1() resolve");
await test1();
console.log("hope to be executed after test1() resolve");
}
/* hope to run code synchronously in the following using .then() keyword */
console.log('1');
doSomething();
console.log('2');
callTest();
console.log('3');
doSomething()
.then(console.log("I want to be after"))
.catch(error =>{
console.log(error);
});
console.log('4');
console.log( doSomethingAsync().then(console.log("I want to be after too")) );
console.log('5');
// hope to run code synchronously in the following using await keyword
(async () => {
let test2 = await doSomethingAsync();
let test3 = await doSomething();
await test1();
console.log(`value doSomethingAsync: ${test2}`);
console.log(`value doSomething: ${test3}`);
})();
console.log('6');
我期望的是看到Promise.resolve()触发后,将代码放入.then()关键字中以同步执行...但这不是我观察到的。在我的终端中查看以下程序输出:
ʘ node test_promises.js
1
2
hope to be executed before test1() resolve
3
I want to be after
4
I want to be after too
Promise { <pending> }
5
6
hope to be executed after test1() resolve
test1, I want to be executed first
I want to be first
I want to be first
I want to be first
value doSomethingAsync: I want to be first
value doSomething: undefined
test1, I want to be executed first
从输出中可以明显看出.then()在被调用函数内的代码之前运行。
异步任务完成后,then函数中的成功或错误处理程序将仅被调用一次。
似乎并非如此。因此,我的问题很简单:
问题:为什么在异步结束之前调用.then(),以及如何正确地使用Promises,.then()和async / await(应该替换掉)进行编码?
编辑
根据社区的回答,我了解到.then()在传递给它的值不是回调函数时直接触发。因此,通过像.then(function() {console.log("I want to be after")} )
好的,我不明白。我得到
ʘ node test_promises.js
1
2
hope to be executed before test1() resolve
3
4
Promise { <pending> }
5
6
hope to be executed after test1() resolve
test1, I want to be executed first
I want to be after too
I want to be first
I want to be first
I want to be after
I want to be first
value doSomethingAsync: I want to be first
value doSomething: undefined
test1, I want to be executed first
我仍然不明白为什么在调用
之前在console.log()触发之前
const callTest = async () => {
console.log("hope to be executed before test1() resolve");
await test1();
console.log("hope to be executed after test1() resolve");
}
感谢社区的耐心
编辑2
来自社区的答案:
异步函数仅等待内部等待的内容 它的代码。它无法自动识别任何可以执行的呼叫 异步的东西。您需要明确承诺setTimeout 使它与承诺一起工作。 – Bergi ANSWER 2:返回setTimeout(() => console.log(“ test1,我想先执行”),3000)不正确,因为setTimeout不会返回promise。转换中 使用回调的函数,例如setTimeout,而不使用其他函数 辅助函数有些罗word:返回新的Promise(resolve => { setTimeout(resolve,3000); }); – Ry-♦
这意味着正确的代码如下:
// declaration of some Promisified functions
const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('I want to be first'), 3000);
});
};
const test1 = async () => { // IMPORTANT CORRECTION: use Promise constructor
return new Promise(resolve => { setTimeout( () => {resolve("test1, I want to be executed first")}, 3000); }); // actuallu async do not transform the return
}; // function into a Promise
// create intermediate calling functions making code synchronous to use console.log() properly
const doSomething = async () => {
console.log( await doSomethingAsync());
};
const callTest = async () => {
console.log("hope to be executed before test1() resolve");
const resultTest1 = await test1(); // IMPORTANT CORRECTION: declare a variable to return the value of the executed function when exec is over, using await
console.log(resultTest1);
console.log("hope to be executed after test1() resolve");
}
// hope to run code synchronously in the following using .then() keyword
console.log('1');
doSomething();
console.log('2');
callTest();
console.log('3');
doSomething()
.then(function() {console.log("I want to be after")} ) // IMPORTANT CORRECTION: declare a callback function instead of executing the function
.catch(error =>{
console.log(error);
});
console.log('4');
console.log( doSomethingAsync().then(function() {console.log("I want to be after too")}) );
console.log('5');
// hope to run code synchronously in the following using await keyword, THIS IS THE "RIGHT" WAY TO USE ASYNC/AWAIT
(async () => {
let test2 = await doSomethingAsync();
let test3 = await doSomething();
await test1(); // this is the last await, it will be the last executed code
console.log(`value doSomethingAsync: ${test2}`);
console.log(`value doSomething: ${test3}`);
})();
console.log('6');
特别感谢所有提供帮助的人。我希望这会有用。