在Promise链上使用 setTimeout

IT技术 javascript json promise
2021-01-26 05:49:43

在这里,我试图围绕Promise。在这里,在第一个请求中,我获取了一组链接。在下一个请求中,我获取了第一个链接的内容。但我想在返回下一个Promise对象之前进行延迟。所以我使用setTimeout on it.But 它给了我以下 JSON 错误 ( without setTimeout() it works just fine)

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

我想知道为什么会失败?

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);
});
6个回答

为了保持Promise链的运行,您不能使用setTimeout()您所做的方式,因为您没有从.then()处理程序返回Promise- 您是从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");
    });
});

在这里,您从.then()处理程序返回一个Promise,因此它被适当地链接起来。


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

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库.delay()

@pdem -v是一个可选值,您希望延迟Promise使用它来解决,从而传递Promise链。 resolve.bind(null, v)代替function() {resolve(v);} 任何一个都可以工作。
2021-03-23 05:49:43
非常感谢...原型延迟有效,但函数 >>> .then 语句无效。t 未定义。
2021-04-01 05:49:43
我已经为 setTimeout 创建了一个Promise包装器来轻松延迟Promise。github.com/zengfenfei/delay
2021-04-04 05:49:43
resolve 函数是 then()..so setTimeout(resolve,t) 的意思是 setTimeout(function(){ return ....},t) 是不是。。。那么为什么它会起作用呢?
2021-04-08 05:49:43
@AL-zami -delay()返回将在setTimeout().
2021-04-09 05:49:43
.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))

更新:

当我需要在异步函数中睡眠时,我会投入

await new Promise(resolve => setTimeout(resolve, 1000))
@AnthonyMoonBeamToorie 已修复,ty
2021-03-28 05:49:43
你不能像这样在异步函数中睡觉吗?等待新的Promise(解决 => setTimeout(解决,1000));
2021-04-03 05:49:43

较短的 ES6 版本的答案:

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

然后你可以这样做:

delay(3000).then(() => console.log('Hello'));
如果您需要该reject选项,例如用于 eslint 验证,则const delay = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
2021-04-11 05:49:43

如果您在.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!!!

快乐编码!

你我的朋友是救生员
2021-04-05 05:49:43

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

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

delay(1000).then(() => console.log('hello'))
我可以确认它在 node.js 8、10、12、13 中有效。不确定你是如何运行你的代码,但我只能假设util它被错误地填充。你在使用捆绑器还是什么?
2021-03-12 05:49:43
我试过这个并得到了无效数量的参数,在延迟函数中预期为 0。
2021-03-18 05:49:43