这是一个简单的案例
var q = new Promise(function(resolve, reject){
resolve(initRequest('get', 'includes/getRemessaRegistrada.php', null, remessasList));
}).then(function(){
console.log('ok');
});
我正在学习javascript承诺概念。为什么在解析处理之前会出现console.log('ok')?
答案 0 :(得分:2)
在您的代码initRequest()
中不会返回任何内容。为了使代码能够正常工作,initRequest()
必须返回与底层异步操作相关联的promise。并且,如果它确实返回了承诺,那么你就不需要另外的包装承诺。
承诺本身没有神奇的力量以某种方式知道底层异步操作何时完成。他们只是没有这样的权力。只有在异步操作以值或错误完成时,在适当的时间调用解析或拒绝promise的异步操作时,promise才有效。然后,承诺用作管理和协调异步结果或错误的更易于使用的界面。
您正在运行initRequest()
,它会启动您的异步操作,然后立即返回,然后很久才会完成,您正在为您的包装承诺调用resolve(undefined)
。此承诺将在initRequest()
完成之前很久就解决,并且不会知道有关异步返回值的任何信息。
这里最好的解决方案是获取或使用XMLHttpRequest的promisified版本,这样你就可以使用只返回promises的函数进行ajax调用。 jQuery有一个内置的。最新的浏览器有fetch()
,它可以执行Ajax并返回一个承诺,并且有许多小型库可用来执行此操作,或者您可以创建自己的库。如果你还没有使用内置这个内置的库(比如jQuery)而你需要专门为此做些什么,我可能会得到fetch()
polyfill,因为这显然是未来浏览器的方向。
如果您只想要一个简单的XHR包装器或使用promise接口进行ajax调用的方法,可以采用以下方法:
How do I promisify native XHR?
我也会发现,因为return req.responseText
函数中有initRequest()
,您可能会认为initRequest()
正在返回该值。它不是。 initRequest()
什么都不返回。 return req.responseText
被返回到异步回调,它只是进入XMLHttpRequest实现的内容。您的initRequest()
函数已经很久很久,已经返回并返回undefined
。有关这种情况的更多信息,请参阅How do I return the response from an asynchronous call?。