我是一个新手javascript开发者,这是我第一次作为stackoverflow用户,但我从这里阅读帖子获得了有价值的信息。
我需要加载一个文件,但代码应该等待,因为它的异步性质。我认为Promise可能会起作用并且它几乎可以工作但它仍然没有等待(同步)文件加载。但是,如果没有文件,它会在最后等待。它应该是另一种方式应该等到文件加载。然后继续并运行需要数据的下一个函数。
谁能告诉我为什么我的承诺不起作用?我是否应该使用此承诺或回电?
以下是代码:
// ...
var p = new Promise(function (resolve, reject) {
let x = getTheData(); // async data but program don’t wait.
if (!x) { //if no data I want to wait?
resolve('success');
console.log('success');
}else {
reject('failure');
console.log('failure');
}
});
p.then(function () {
let y = getNewFunctionThatNeedsTheAboveDataToWork();
res.send('y is not working ' + y);
}).catch(function(){
console.log('error');
});
return p;
我完全迷失了,任何帮助都会优雅。
答案 0 :(得分:0)
这里的问题是getData是异步的,所以你需要一些方法来知道它何时完成。这意味着getData需要返回一个promise(更新的方式),或者接受一个回调作为参数(旧的方式)。下面是一个例子,说明getData如何与promises一起使用来通过web调用来获取数据(这在jQuery.get中会更加简单,但是让我们暂时坚持使用纯javascript):
var getData = function() {
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4 && this.status != 200) {
console.log('Data request returned an error');
reject('failure');
} else if (this.readyState === 4 && this.status === 200) {
resolve(this.responseText);
}
});
xhr.open("GET", "https://httpbin.org/get", true); // true = async
xhr.send();
})
return(p)
}
然后我们可以像这样使用这个函数:
getData().then(function(d) {
console.log(d);
// do something useful with d
})
或者,您可以使用回调完成相同的操作:
var getData2 = function (cb) {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4 && this.status != 200) {
console.log('Data request returned an error');
cb(null, "error");
} else if (this.readyState === 4 && this.status === 200) {
cb(this.responseText);
}
});
xhr.open("GET", "https://httpbin.org/get", true);
xhr.send();
}
getData2(function(d, e) {
if(e) {
console.log("oops. there was an error: ", e);
} else {
console.log(d);
}
})
最后,如果getData函数来自其他地方并且您无法更改它,则可以将其从回调样式函数转换为promise样式函数。这是一种方式:
var promiseMe = new Promise(function (resolve, reject) {
getData2(function(d, e) {
if(e) {
reject(e)
} else {
resolve(d)
}
})
})
promiseMe.then(function(d) {
console.log(d)
})
修改强>
以上在浏览器中有效。这是在节点中执行此操作的一种方法:
http = require('http');
var getData = function() {
var p = new Promise(function (resolve, reject) {
var data = '';
http.get('http://httpbin.org/get', function(res) {
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(data);
});
})
})
return(p)
}
getData().then(function(d) {
console.log(d)
})
我希望这些例子能够开始清理。