在promise链

时间:2016-09-16 18:59:56

标签: javascript json promise

在这里,我试图围绕promises.Here第一次请求我获取一组链接。在下一个请求我获取第一个链接的内容。但我想在返回下一个promise对象之前做出延迟。所以我在它上面使用了setTimeout。但是它给了我以下JSON错误( without setTimeout() it works just fine

  

SyntaxError:JSON.parse:第1行第1列的意外字符   JSON数据

我想知道它失败的原因?

let globalObj={};
function getLinks(url){
    return new Promise(function(resolve,reject){

       let http = new XMLHttpRequest();
       http.onreadystatechange = function(){
            if(http.readyState == 4){
              if(http.status == 200){
                resolve(http.response);
              }else{
                reject(new Error());
              }
            }           
       }
       http.open("GET",url,true);
       http.send();
    });
}

getLinks('links.txt').then(function(links){
    let all_links = (JSON.parse(links));
    globalObj=all_links;

    return getLinks(globalObj["one"]+".txt");

}).then(function(topic){


    writeToBody(topic);
    setTimeout(function(){
         return getLinks(globalObj["two"]+".txt"); // without setTimeout it works fine 
         },1000);
});

5 个答案:

答案 0 :(得分:136)

为了保持承诺链,你不能像你所做的那样使用setTimeout(),因为你没有从.then()处理程序返回一个承诺 - 你从{{返回} 1}}回调对你没有好处。

相反,你可以制作一个简单的小延迟函数:

setTimeout()

然后,就像这样使用它:

function delay(t, v) {
   return new Promise(function(resolve) { 
       setTimeout(resolve.bind(null, v), t)
   });
}

在这里,您将从getLinks('links.txt').then(function(links){ let all_links = (JSON.parse(links)); globalObj=all_links; return getLinks(globalObj["one"]+".txt"); }).then(function(topic){ writeToBody(topic); // return a promise here that will be chained to prior promise return delay(1000).then(function() { return getLinks(globalObj["two"]+".txt"); }); }); 处理程序返回一个承诺,因此它被链接得恰当。

您还可以向Promise对象添加延迟方法,然后直接在您的承诺上使用.then()方法,如下所示:

.delay(x)

或者,使用内置function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); } Promise.prototype.delay = function(t) { return this.then(function(v) { return delay(t, v); }); } Promise.resolve("hello").delay(500).then(function(v) { console.log(v); });方法的Bluebird promise library

答案 1 :(得分:56)

.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))

答案 2 :(得分:17)

答案的较短的ES6版本:

const delay = t => new Promise(resolve => setTimeout(resolve, t));

然后您可以这样做:

delay(3000).then(() => console.log('Hello'));

答案 3 :(得分:4)

如果您位于 .then()块中,并且您想要执行 settimeout()

            .then(() => {
                console.log('wait for 10 seconds . . . . ');
                return new Promise(function(resolve, reject) { 
                    setTimeout(() => {
                        console.log('10 seconds Timer expired!!!');
                        resolve();
                    }, 10000)
                });
            })
            .then(() => {
                console.log('promise resolved!!!');

            })

输出如下所示

wait for 10 seconds . . . .
10 seconds Timer expired!!!
promise resolved!!!

快乐的编码!

答案 4 :(得分:1)

在node.js中,您还可以执行以下操作:

const { promisify } = require('util')
const delay = promisify(setTimeout)

delay(1000).then(() => console.log('hello'))