所以我试图将我的代码转移到"Promise world",并且在很多地方,当我不得不"循环"异步功能时 - 我只是以这种方式使用递归
function doRecursion(idx,callback){
if(idx < someArray.length){
doAsync(function(){
doRecursion(++idx,callback)
});
}else{
callback('done!')
}
}
doRecursion(0,function(msg){
//...
});
Run Code Online (Sandbox Code Playgroud)
现在我正试图改变进入Promise世界,我很困惑
var Promise = require('bluebird')
function doRecursion(idx){
return new Promise(function(resolve){
if(idx < someArray.length){
doAsync(function(){
//... doRecursion(++idx)
// how do i call doRecusion here....
});
}else{
resolve('done!')
}
});
}
doRecursion(0).then(function(msg){
//...
});
Run Code Online (Sandbox Code Playgroud)
谢谢.
所以我正在制作一个用于学习目的的小爬虫,最终我应该得到网站上页面的树状结构。
我一直在绞尽脑汁试图让这些要求正确。这或多或少是我所拥有的:
var request = require('request');
function scanPage(url) {
// request the page at given url:
request.get(url, function(err, res, body) {
var pageObject = {};
/* [... Jquery mumbo-jumbo to
1. Fill the page object with information and
2. Get the links on that page and store them into arrayOfLinks
*/
var arrayOfLinks = ['url1', 'url2', 'url3'];
for (var i = 0; i < arrayOfLinks.length; i++) {
pageObj[arrayOfLinks[i]] = scanPage[arrayOfLinks[i]];
}
});
return pageObj;
}
Run Code Online (Sandbox Code Playgroud)
我知道这段代码在很多层面上都是错误的,但它应该让您了解我正在尝试做什么。
我应该如何修改它才能使其正常工作?(如果可能的话,不使用承诺)
(您可以假设该网站具有树状结构,因此每个页面仅具有指向三个页面下方页面的链接,因此采用递归方法)
当我仅在满足各种条件时才执行算法中的后续步骤时,我会这样表达:
if (sc1 || sc2) {
do();
various();
things();
}
Run Code Online (Sandbox Code Playgroud)
当我仅根据承诺的履行执行后续步骤时,我可以这样表达:
asyncCheck().then(ac1 => {
if (ac1) {
do();
various();
things();
}
}
Run Code Online (Sandbox Code Playgroud)
当条件sc1只是一个常规的旧同步表达式但条件ac2通过承诺异步出现时,我如何用惯用的 JavaScript表达?
假设原生 ES6 承诺和非平凡代码在满足条件时被执行。
例如,这种“明显”的方式看起来很丑陋:
if (sc1) {
do();
various();
things();
} else {
asyncCheck().then(ac2 => {
if (ac2) {
do();
various();
things();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以将重复的代码放在一个以任何方式调用的函数中,这样不那么难看,但我觉得我可能会遗漏一些其他 JavaScript 程序员可能正在使用的更惯用的东西。
我也应该添加这个观察:因为在我的情况下,有一个合乎逻辑的 or,它应该短路,所以如果简单检查已经是false.
我知道在Nodejs / Express中兑现承诺的最佳方法是:
doSomeThing()
.then()
.then()
.catch();
Run Code Online (Sandbox Code Playgroud)
但是最近不得不使用async和q模块来遍历列表/数组并运行async函数。我想知道这样做/编写此方法的更好方法-
var deferred = Q.defer();
var deferred2 = Q.defer();
models.Local.findOne({
where: {
id: parseInt(req.body.localid)
}
})
.then(function(resultLocal){
if(!resultLocal){
return res.status(404).json(
{
"status" : "error",
'error': "Local Not Found"
});
}
return models.Documents.create(req.body.document);
})
.then(function(docCreated){
var attributes = req.body.document.Attributes;
async.each(attributes, function(item, callback) {
models.Doc_Tags.create({
value: item.value,
attribute_id: item.id,
document_id: docCreated.id
})
.then(function(attributeCreated){
var upObj = {};
upObj[item.col_name] = item.value;
models[item.table_name].update(upObj,{
where:{
id: req.body.document.local_id
}
})
.then(function(primaryUpdated){
deferred2.resolve();
})
.catch(function(error){
return res.status(400).json({status: 'error', error:error.message});
}); …Run Code Online (Sandbox Code Playgroud) 我从 E6 Promises 开始。我非常喜欢它们,但有一个关于错误处理的重要概念,我不明白,希望得到一些澄清。
让我们假设以下简单的函数返回一个承诺:
function promiseString(str, timeout, doResolve) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (doResolve) {
resolve(str);
} else {
reject(new Error("Rejecting " + str));
}
}, timeout);
});
}
Run Code Online (Sandbox Code Playgroud)
它非常简单,只为传递给它的字符串返回一个承诺,并导致该承诺在“超时”毫秒内被解析或拒绝(基于第三个参数)。
我可以按预期完全消耗它,如下所示:
promiseString("One", 100, true)
.then((str) => { console.log("First then is " + str); return promiseString(str + " two", 100, true); })
.then((str) => { console.log("Second then is " + str); return promiseString(str + " three", 100, true); })
.then((str) => console.log(str))
.catch((err) => …Run Code Online (Sandbox Code Playgroud) function getNamesById(nameIds) {
var defer = $q.defer();
var result = [];
nameIds.forEach(function (nameId) {
account.getNameById(nameId).then(function (name) {
result[nameId] = name;
});
});
defer.resolve(result);
return defer.promise;
}
Run Code Online (Sandbox Code Playgroud)
我上面的代码显然没有按预期工作。我必须迭代一个 id 数组并构造另一个以 id 作为键的数组,以及从异步函数获取的值
我有一个函数,它将一个对象传递给它,其中键和数据是一个数组.我必须调用API来获取附加信息,然后将其添加回对象并返回整个对象.
我的第一种方法是不正确的,因为我试图将数据传出.then(),但这是错误的做法.
function asignChecklistItems(taskArray) {
// get all the people's tasks passed in
return new Promise(function(resolve, reject) {
var promises = []
// Task Array: {"Person":[tasks,tasks,tasks]}
for (var person in taskArray) {
var individualTaskPerson = taskArray[person]
// get the person's tasks
for (var individualTask in individualTaskPerson) {
// here we get each individual task
var task = individualTaskPerson[individualTask]
// Check if the checklist is present, the .exists is a bool
if (task.checklist.exists === true) {
//Here we push …Run Code Online (Sandbox Code Playgroud) 我希望遍历一组用户(仅设置 id 属性),每两秒使用每个 id 调用一个端点,并将响应中关联的用户名存储到更新的数组中。
例如更新 [{ id: 1 }] 到 [{ id: 1, name: "Leanne Graham" }]
这是我的代码:
const axios = require('axios');
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
function addNameToUser(user) {
return new Promise((resolve) => {
axios.get(`https://jsonplaceholder.typicode.com/users/${user.id}`)
.then(response => {
user.name = response.data.name
resolve(user);
});
})
}
const requests = users.map((user, index) => {
setTimeout(() => {
return addNameToUser(user);
}, index * 2000);
});
Promise.all(requests).then((updatedArr) => {
console.log(updatedArr); …Run Code Online (Sandbox Code Playgroud) node.js 8.10
puppeteer 1.10.0
我有一个小型网络抓取应用程序,它从基于 Java Server Faces 的网络应用程序下载多个文件。单击每个文件的链接会触发下载。不幸的是,没有下载的直接 url,我必须这样做。
如果我在两次运行之间保持浏览器实例处于活动状态,它就可以正常工作。出于稳定性原因,我想在两次运行之间关闭实例。当我打电话时,browser.close()我的下载已停止,因为 chrome 实例在下载完成之前已关闭。
puppeteer 是否提供了一种检查下载是否仍处于活动状态并等待下载完成的方法?我试过page.waitForNavigation({ waitUntil: "networkidle0" })and "networkidle2",但那些似乎无限期地等待。
谢谢!
以下发出一个unhandledrejection事件,但似乎“工作”。
for...await 似乎通过发出异常来响应被拒绝的承诺(尽管在第一个承诺已经解决之后)。
我可以unhandledrejection使用Promise.alland避免该事件Promise.allSettled。以下代码是反模式吗?
async function asyncFunction() {
try {
const happy = new Promise((resolve)=>setTimeout(()=>resolve('success'), 1000))
const sad = new Promise((_,reject)=>setTimeout(()=>reject('failure')))
const promises = [happy, sad]
for await(const item of promises) {
console.log(item)
}
} catch (err) {
console.log(`an error occurred:`, err)
}
}
asyncFunction()Run Code Online (Sandbox Code Playgroud)
javascript ×9
promise ×7
node.js ×6
asynchronous ×2
angularjs ×1
arrays ×1
ecmascript-6 ×1
es6-promise ×1
express ×1
puppeteer ×1
q ×1
recursion ×1
settimeout ×1
web-scraping ×1