Javascript承诺在我的情况下不起作用

时间:2016-07-08 18:08:06

标签: javascript promise ecmascript-6

这是一个简单的案例

var q = new Promise(function(resolve, reject){
        resolve(initRequest('get', 'includes/getRemessaRegistrada.php', null, remessasList));
    }).then(function(){
        console.log('ok');
    });

我正在学习javascript承诺概念。为什么在解析处理之前会出现console.log('ok')?

1 个答案:

答案 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?

XR

Fetch Polyfill

我也会发现,因为return req.responseText函数中有initRequest(),您可能会认为initRequest()正在返回该值。它不是。 initRequest()什么都不返回。 return req.responseText被返回到异步回调,它只是进入XMLHttpRequest实现的内容。您的initRequest()函数已经很久很久,已经返回并返回undefined。有关这种情况的更多信息,请参阅How do I return the response from an asynchronous call?