Node.js Promise - 代码不应该等到 .then 完成 () 吗?
Node.js Promise - Shouldn't code wait until .then is complete()?
我对这种异步行为感到困惑。
当 token
为 false
时,refreshToken()
函数运行但 createTokenFile()
不等待它完成。
不应该 var tokenDate = new Date(token.expires);
在 callApiToken().then(function() {refreshToken();})
完成后再执行吗?
function createTokenFile() {
console.log("No token-file.json file found. " .red +
"Please complete for a new one." .red);
return callApiToken().then(function() {
refreshToken();
});
}
function checkExpiredToken() {
return new Promise(function(resolve, reject) {
if (!token) {
refreshToken();
}
var tokenDate = new Date(token.expires);
var utc = new Date().toUTCString();
var now = new Date(utc);
}
function refreshToken() {
try {
var tokenFile = path.join(__dirname, 'token-file.json');
console.log(tokenFile);
return token = JSON.parse(fs.readFileSync(tokenFile, {encoding: 'utf-8'}));
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
} else {
return createTokenFile();
}
}
}
更新为 refreshToken()
保证不会去同步代码。 异步 的函数将永远如此。因此,如果 refreshToken
是异步的,那么上面的使用将不会等待它完成后再继续。
您的代码示例留给想象的空间太多(更不用说语法错误了),因此没有更好的答案。也许尝试在 jsbin.com 或 jsfiddle.net.
中重现这种情况
Shouldn't var tokenDate = new Date(token.expires);
wait after callApiToken().then(function() {refreshToken();})
to finish before executing?
不 - 它不在等待承诺解决的 .then()
回调中。它只等到创建 promise - 但 promise 解析(你称之为 "finish")是异步的。请注意,承诺不是魔法,它们是 just callbacks.
要修复您的代码,
- 在
createTokenFile
中,您需要 return
来自 then
回调的 refreshToken()
checkExpiredToken
应该 not use the Promise
constructor
refreshToken
应该总是return一个承诺
- 没有理由
refreshToken
会同步读取文件
- 您不应将
token
缓存为包含值 的全局变量
function createTokenFile() {
console.log("No token-file.json file found. " +
"Please complete for a new one.");
return callApiToken();
}
function checkExpiredToken() {
return (tokenPromise || refreshToken())
.then(function(token) {
var tokenDate = new Date(token.expires);
var utc = new Date().toUTCString();
var now = new Date();
});
}
function refreshToken() {
var tokenFile = path.join(__dirname, 'token-file.json');
console.log(tokenFile);
return tokenPromise = readFileAsync(tokenFile, {encoding: 'utf-8'}))
.then(JSON.parse)
.catch(function(err) {
if (err.code !== 'ENOENT') {
throw err;
} else {
return createTokenFile().then(refreshToken);
}
});
}
(其中 readFileAsync
是 fs.readFile
的 promisified 版本)
我对这种异步行为感到困惑。
当 token
为 false
时,refreshToken()
函数运行但 createTokenFile()
不等待它完成。
不应该 var tokenDate = new Date(token.expires);
在 callApiToken().then(function() {refreshToken();})
完成后再执行吗?
function createTokenFile() {
console.log("No token-file.json file found. " .red +
"Please complete for a new one." .red);
return callApiToken().then(function() {
refreshToken();
});
}
function checkExpiredToken() {
return new Promise(function(resolve, reject) {
if (!token) {
refreshToken();
}
var tokenDate = new Date(token.expires);
var utc = new Date().toUTCString();
var now = new Date(utc);
}
function refreshToken() {
try {
var tokenFile = path.join(__dirname, 'token-file.json');
console.log(tokenFile);
return token = JSON.parse(fs.readFileSync(tokenFile, {encoding: 'utf-8'}));
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
} else {
return createTokenFile();
}
}
}
更新为 refreshToken()
保证不会去同步代码。 异步 的函数将永远如此。因此,如果 refreshToken
是异步的,那么上面的使用将不会等待它完成后再继续。
您的代码示例留给想象的空间太多(更不用说语法错误了),因此没有更好的答案。也许尝试在 jsbin.com 或 jsfiddle.net.
中重现这种情况Shouldn't
var tokenDate = new Date(token.expires);
wait aftercallApiToken().then(function() {refreshToken();})
to finish before executing?
不 - 它不在等待承诺解决的 .then()
回调中。它只等到创建 promise - 但 promise 解析(你称之为 "finish")是异步的。请注意,承诺不是魔法,它们是 just callbacks.
要修复您的代码,
- 在
createTokenFile
中,您需要return
来自then
回调的refreshToken()
checkExpiredToken
应该 not use thePromise
constructorrefreshToken
应该总是return一个承诺- 没有理由
refreshToken
会同步读取文件 - 您不应将
token
缓存为包含值 的全局变量
function createTokenFile() {
console.log("No token-file.json file found. " +
"Please complete for a new one.");
return callApiToken();
}
function checkExpiredToken() {
return (tokenPromise || refreshToken())
.then(function(token) {
var tokenDate = new Date(token.expires);
var utc = new Date().toUTCString();
var now = new Date();
});
}
function refreshToken() {
var tokenFile = path.join(__dirname, 'token-file.json');
console.log(tokenFile);
return tokenPromise = readFileAsync(tokenFile, {encoding: 'utf-8'}))
.then(JSON.parse)
.catch(function(err) {
if (err.code !== 'ENOENT') {
throw err;
} else {
return createTokenFile().then(refreshToken);
}
});
}
(其中 readFileAsync
是 fs.readFile
的 promisified 版本)