我正在学习节点和承诺。我已经简化了我的问题并在下面分享了我的代码。
我有三个模块:app.js,modLanguage.js和model.js
app.js:
var l = require('../test/modLanguage.js');
var params = [{
p0: 'johnDoe',
p1: '12345',
p2: 0
}];
var lang = l.call(params);
console.log("Needs to run last: " + lang.language);
modLanguage.js:
var call = function(params) {
var langQuery = require('../test/model.js');
var userLang = createLanguage();
userLang.setLanguage('FRENCH');
console.log("This needs to run first - setting lang French before DB dip: " + userLang.language);
var myData = langQuery.getLanguage(params)
// My DB dip
.then(function(data) {
var data = JSON.parse(JSON.stringify(data[0]));
userLang.setLanguage(data[0].Language);
console.log("Needs to run second - DB dip brought language ENG: " + userLang.language);
return userLang;
})
.catch(function(err) {
console.log('error');
});
return userLang;
}
module.exports.call = call;
function createLanguage() {
return {
language: this.language,
setLanguage: function(language) {
this.language = language;
return this.language;
}
}
}
model.js是一个简单的模块,它使用params,运行存储过程并通过返回promise来返回数据。
我想阻止在app.js上运行代码,直到从针对Database dip返回的数据初始化对象。但是,按原样,console.log显示:
这需要先运行 - 在DB dip之前设置lang French:FRENCH
最后需要跑:法语
需要跑第二名 - DB dip带来语言ENG:ENG
我想要达到的目的显然是:
这需要先运行 - 在DB dip之前设置lang French:FRENCH
需要跑第二名 - DB dip带来语言ENG:ENG
需要最后运行:ENG
请告知我为实现这一目标需要做出哪些改变?
答案 0 :(得分:1)
以下是需要更改的行以及原因。
// Instead of assigning this promise to a variable that you never
// even use, just return the promise to the caller, so caller can wait
// for a result to actually be there.
return langQuery.getLanguage(params)
// Returning userLang will cause your app to process userLang
// before you've attached the proper language to it. Don't return
// it. Instead, return the promise that tells you userLang will
// be ready, as described above.
return userLang; // delete this line
// Now that the promise is returned instead of an incomplete
// object, we can wait for the promise to resolve before logging.
var lang = l.call(params).then(lang =>
console.log("Needs to run last: " + lang.language)
);
这是一个演示的工作片段。
作为旁注,var
基本上不赞成let
,它的行为几乎完全相同,除了修复了一些问题!范围界定。
我认为在此示例中,使用const
比let
更好于let
,但代表您使用var
,因为它距离小得多使用var
。
如果您使用的代码库强制您使用var
,请确保您研究let
/ var
之间的差异,否则只需使用{{1}退出你的生活会更好。
/** some mock-ups to make the example run in a snippet **/
const module = {exports: {}}
let modelMock = {
getLanguage(params){
return Promise.resolve([[{
Language: 'en-us'
}]])
}
}
function require (path) {
if (path === '../test/model.js')
return modelMock;
if (path === '../test/modLanguage.js')
return module.exports;
}
/********* log to output pre instead of console *********/
console.log = (...args) =>
[...args].forEach(arg =>
document.querySelector('pre').innerText += '\n' + arg
);
/******************* modLanguage.js *********************/
let call = function(params) {
let langQuery = require('../test/model.js');
let userLang = createLanguage();
userLang.setLanguage('FRENCH');
console.log(
'This needs to run first - setting lang French before DB dip: '
+ userLang.language
);
return langQuery.getLanguage(params)
// My DB dip
.then(function(data) {
// JSON.parse is known to throw. We should always wrap it
// in a try catch block and decide how to deal with the error.
// In this case, I'm just rethrowing with clearer message.
try { data = JSON.parse(JSON.stringify(data[0])); }
catch(e) {
e. message =
'langQuery.getLanguage could not parse provided data';
throw e;
}
userLang.setLanguage(data[0].Language);
console.log(
'Needs to run second - DB dip brought language ENG: '
+ userLang.language
);
return userLang;
})
.catch(function(err) {
console.error('error');
});
}
module.exports.call = call;
function createLanguage() {
return {
language: this.language,
setLanguage: function(language) {
this.language = language;
return this.language;
}
}
}
/************************ app.js ************************/
let l = require('../test/modLanguage.js');
let params = [{
p0: 'johnDoe',
p1: '12345',
p2: 0
}];
l.call(params).then(lang =>
console.log("Needs to run last: " + lang.language)
);

<pre></pre>
&#13;
答案 1 :(得分:0)
您可以从call
返回承诺。不要直接使用返回值设置lang
并l.call(...).then(...);
进行最后一次调用并在回调中设置lang
。