Здесь я пытаюсь сосредоточиться на обещаниях. Здесь по первому запросу я получаю набор ссылок, а по следующему запросу я получаю содержимое первой ссылки. Но я хочу сделать задержку перед возвратом следующего объекта обещания. Поэтому я использую 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);
});
javascript
json
promise
AL-З
источник
источник
return
это зависит от функции и возвращается только в родительскую функцию, и что вы не можете вернуться из асинхронного метода.globalObj
.JSON.parse
бросает? Мне трудно поверить, что наличиеsetTimeout
в одномthen
обратном вызове влияет на вызов в предыдущемthen
обратном вызове .Ответы:
Чтобы цепочка обещаний продолжалась, вы не можете использовать
setTimeout()
то, что делали, потому что вы не возвращаете обещание от.then()
обработчика - вы возвращаете его изsetTimeout()
обратного вызова, который вам не помогает.Вместо этого вы можете сделать простую небольшую функцию задержки, например:
А затем используйте это так:
Здесь вы возвращаете обещание от
.then()
обработчика и, таким образом, оно соответствующим образом связано.Вы также можете добавить метод задержки к объекту Promise, а затем напрямую использовать
.delay(x)
метод в своих обещаниях, например:Или используйте библиотеку обещаний Bluebird, в которой уже есть
.delay()
встроенный метод.источник
delay()
возвращает обещание, которое будет разрешено послеsetTimeout()
.v
это необязательное значение, с которым вы хотите, чтобы обещание задержки разрешалось и, таким образом, передавалось по цепочке обещаний.resolve.bind(null, v)
вместоfunction() {resolve(v);}
Either будет работать.ОБНОВИТЬ:
когда мне нужно спать в асинхронной функции, я добавляю
источник
Более короткая версия ответа ES6:
И тогда вы можете:
источник
reject
опция, например, для проверки eslint, тоconst delay = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
Если вы находитесь внутри блока .then () и хотите выполнить settimeout ()
вывод будет, как показано ниже
Удачного кодирования!
источник
В node.js вы также можете делать следующее:
источник
util
, что полифиллинг выполняется неправильно. Вы используете упаковщик или что-то в этом роде?