如何正确链接包含在promises中的不同异步操作

时间:2017-03-21 09:58:42

标签: javascript ajax asynchronous promise xmlhttprequest

目前,我对promises的理解仅仅是对外部环境(浏览器,node.js等)本机异步函数的包装器的理解。我很困惑如何实际编写使用promises正确连接异步操作的软件。这是我的问题:

在下面的代码中,setTimeout函数包含在一个promise中。我还在一个承诺中包含XMLHttpRequest电话。我假设(错误的)如果我按照以下方式将它们链接在一起,计时器将运行,然后然后将进行AJAX调用。这不会发生。 AJAX调用首先发生。

timer(1000).then(AJAXGetRequest('https://itunes.apple.com/hk/rss/topalbums/limit=10/json'))

如果我将我的保证链更改为如下所示,它会按预期工作!

timer(1000).then(function(){
    AJAXGetRequest('https://itunes.apple.com/hk/rss/topalbums/limit=10/json')
})

上述代码的问题在于我正在恢复使用异步操作的回调。 我假设有一种方法来编写我的代码,所以我不必回复回调,我可以这样做:

timer(1000)
    .then(AJAXGetRequest('some/api'))
    .then(timer)  // wait
    .then(AJAXGetRequest('someOther/api'))
    .then(timer)  // wait
    .then(AJAXGetRequest('another/api'))
                  // wait

甚至更灵活:

timer(1000)
    .then(AJAXGetRequest('some/api'))
    .then(timer(200))  // wait
    .then(AJAXGetRequest('someOther/api'))
    .then(timer(600))  // wait
    .then(AJAXGetRequest('another/api'))
                  // wait

以下示例的其余代码如下:

let timer = function(value) {
    return new Promise((resolve, reject) => {

        setTimeout(() => {

            console.log(value);
            resolve(value); 

        }, value);

    });
};


let AJAXGetRequest = function(URL) {
    return new Promise((resolve, reject) => {

        var getRequest = new XMLHttpRequest();
        getRequest.open('get', URL, true);
        getRequest.send();

        getRequest.onload = function() {

            var JSONObject = JSON.parse(getRequest.responseText);
            console.log(JSONObject);
            resolve(JSONObject); // object
        }


    });
};

1 个答案:

答案 0 :(得分:1)

<Promise>.then需要一个函数,如果你给它一个承诺,它将不知道如何处理它。

您可以通过将传入的内容更改为.then来匹配该签名来解决此问题:

timer(1000)
.then(() => AjaxRequest(url1))
.then(() => timer(1000))
.then(() => AjaxRequest(url2))
.then(() => timer(1000));