如何等待值被添加到数组?
How to await values being added to array?
我有一个项目,我正在使用 Request-Promise 和 Cheerio 解析快餐菜单,然后根据用户的要求返回“订单”。但是,我在输出存储为数组的“订单”时遇到了一些问题。
var rp = require('request-promise');
var cheerio = require('cheerio');
var tempMenu = [];
var order = [];
function getItem(item) {
var itemUrl = baseURL + '/' + item
var itemMenu = {
uri: itemUrl,
transform: function (body) {
return cheerio.load(body);
}
};
rp(itemMenu)
.then(function ($) {
//.class #id tag
$(".product-card .product-name a").each(function () {
tempMenu.push($(this).text());
order.push(tempMenu[Math.floor(Math.random() * tempMenu.length)]);
});
console.log(order)
})
.catch(function (err) {
});
}
getItem('drinks')
console.log(order)
目前,输出是:
[]
[
'drink1',
'drink2',
'drink3'
]
如果我将代码更改为以下内容:
rp(itemMenu)
.then(function ($) {
//.class #id tag
$(".product-card .product-name a").each(function () {
tempMenu.push($(this).text());
order.push(tempMenu[Math.floor(Math.random() * tempMenu.length)]);
});
console.log(1)
})
.catch(function (err) {
});
}
getItem('drinks')
console.log(2)
日志是
2
1
所以我知道我的问题是当我尝试输出“order”数组时它没有被填充,因为它首先被记录,我的问题是我如何等待数组被填充,然后输出它?
之所以会这样,是因为then cb函数进入了回调队列。
您应该将它们都包装在一个异步函数中,并在您要等待的部分使用 await。
这应该可以解决您的问题。
您的 getItem
函数应该 return 一个 Promise
and then you can either use the Promise.prototype.then()
method on it or the await
关键字以确保您在尝试处理结果之前等待结果。
这是一个简单的示例,其中包含一些伪造的 rp
函数和数据:
// Fake:
const rp = (item) => {
console.log(`Fetching ${ item }...`);
return new Promise((resolve) => {
setTimeout(() => {
resolve(Math.random());
}, 1000 + Math.random() * 2000)
});
}
function getItem(item) {
const order = [];
// This `getItem` function returns a Promise...
return rp(item).then((randomNumber) => {
for (let i = 0; i < 10; ++i) {
order.push(`${ item } ${ randomNumber + i }`);
}
// ...and when this Promise resolves, it will return the `order`
// array with the right values in it:
return order;
});
}
getItem('Drinks').then(order => console.log(order));
console.log('This is executed after calling getItem, but we ware still waiting for the Promise to resolve...');
.as-console-wrapper {
max-height: none !important;
}
替代async/await
:
// Fake:
const rp = (item) => {
console.log(`Fetching ${ item }...`);
return new Promise((resolve) => {
setTimeout(() => {
resolve(Math.random());
}, 1000 + Math.random() * 2000)
});
}
function getItem(item) {
const order = [];
// This `getItem` function returns a Promise...
return rp(item).then((randomNumber) => {
for (let i = 0; i < 10; ++i) {
order.push(`${ item } ${ randomNumber + i }`);
}
// ...and when this Promise resolves, it will return the `order`
// array with the right values in it:
return order;
});
}
// You can't use `await` outside an `async` function, so we define this first...:
async function loadDataWithAwait() {
const order = await getItem('Food');
console.log('This won\'t be executed until getItem\'s Promise is resolved:');
console.log(order);
}
// ...and now call it:
loadDataWithAwait();
.as-console-wrapper {
max-height: none !important;
}
我有一个项目,我正在使用 Request-Promise 和 Cheerio 解析快餐菜单,然后根据用户的要求返回“订单”。但是,我在输出存储为数组的“订单”时遇到了一些问题。
var rp = require('request-promise');
var cheerio = require('cheerio');
var tempMenu = [];
var order = [];
function getItem(item) {
var itemUrl = baseURL + '/' + item
var itemMenu = {
uri: itemUrl,
transform: function (body) {
return cheerio.load(body);
}
};
rp(itemMenu)
.then(function ($) {
//.class #id tag
$(".product-card .product-name a").each(function () {
tempMenu.push($(this).text());
order.push(tempMenu[Math.floor(Math.random() * tempMenu.length)]);
});
console.log(order)
})
.catch(function (err) {
});
}
getItem('drinks')
console.log(order)
目前,输出是:
[]
[
'drink1',
'drink2',
'drink3'
]
如果我将代码更改为以下内容:
rp(itemMenu)
.then(function ($) {
//.class #id tag
$(".product-card .product-name a").each(function () {
tempMenu.push($(this).text());
order.push(tempMenu[Math.floor(Math.random() * tempMenu.length)]);
});
console.log(1)
})
.catch(function (err) {
});
}
getItem('drinks')
console.log(2)
日志是
2
1
所以我知道我的问题是当我尝试输出“order”数组时它没有被填充,因为它首先被记录,我的问题是我如何等待数组被填充,然后输出它?
之所以会这样,是因为then cb函数进入了回调队列。 您应该将它们都包装在一个异步函数中,并在您要等待的部分使用 await。
这应该可以解决您的问题。
您的 getItem
函数应该 return 一个 Promise
and then you can either use the Promise.prototype.then()
method on it or the await
关键字以确保您在尝试处理结果之前等待结果。
这是一个简单的示例,其中包含一些伪造的 rp
函数和数据:
// Fake:
const rp = (item) => {
console.log(`Fetching ${ item }...`);
return new Promise((resolve) => {
setTimeout(() => {
resolve(Math.random());
}, 1000 + Math.random() * 2000)
});
}
function getItem(item) {
const order = [];
// This `getItem` function returns a Promise...
return rp(item).then((randomNumber) => {
for (let i = 0; i < 10; ++i) {
order.push(`${ item } ${ randomNumber + i }`);
}
// ...and when this Promise resolves, it will return the `order`
// array with the right values in it:
return order;
});
}
getItem('Drinks').then(order => console.log(order));
console.log('This is executed after calling getItem, but we ware still waiting for the Promise to resolve...');
.as-console-wrapper {
max-height: none !important;
}
替代async/await
:
// Fake:
const rp = (item) => {
console.log(`Fetching ${ item }...`);
return new Promise((resolve) => {
setTimeout(() => {
resolve(Math.random());
}, 1000 + Math.random() * 2000)
});
}
function getItem(item) {
const order = [];
// This `getItem` function returns a Promise...
return rp(item).then((randomNumber) => {
for (let i = 0; i < 10; ++i) {
order.push(`${ item } ${ randomNumber + i }`);
}
// ...and when this Promise resolves, it will return the `order`
// array with the right values in it:
return order;
});
}
// You can't use `await` outside an `async` function, so we define this first...:
async function loadDataWithAwait() {
const order = await getItem('Food');
console.log('This won\'t be executed until getItem\'s Promise is resolved:');
console.log(order);
}
// ...and now call it:
loadDataWithAwait();
.as-console-wrapper {
max-height: none !important;
}