![](/img/trans.png)
[英]How to use "async/await" and "promises" for synchromous execution in Node.js?
[英]How to use async or promises Node/Express
我在這里發布了先前的問題,即如何解決Node.js / Express中的競爭條件。 我的控制台可以正確更新,但我的網頁無法更新的地方
基本上,我想知道如何在網頁更新之前完成代碼的加載。 我聽說了promise或async的工作,但是我無法在我的代碼中正確使用它們。 我在下面做了一個簡單的代碼版本。 目前,當我加載頁面時,我的天氣功能已正確更新,但是flickr API需要再加載兩次頁面才能顯示其結果。 有人可以告訴我如何使用異步或Promises加載我的所有數據並立即更新頁面嗎?
app.get('/', function (req, res) {
// Render the webpage
res.render('index', {weather: null, headlocation: null, lat: null, long: null, imgLinks: null, WebLinks: null, imgLinksFl: null, restLat: null, restLong: null, restname: null, error: null});
})
// Main Page
app.post('/', function (req, res) {
city = req.body.city; // Grab the users input city
//console.log(weatherSort); // Debugging
weatherSearch(); // Openweather API
filckrSearch(); // Flickr API
res.render('index', {weather: weatherText, headlocation: headLocationText, lat: latLocation, long: longLocation, imgLinks: imageLinks, WebLinks: websiteLinks, imgLinksFl: imageLinksFlick, restLat: latitudeRest, restLong: longitudeRest, restname: restName, error: null});
});
// Weather function
function weatherSearch(){
// API URL
let urlw = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKeyWeather}`
// Send out a request
request(urlw, function (err, response, bodyW) {
// Check for errors
if(err || (JSON.parse(bodyW).cod == '404') || (JSON.parse(bodyW).cod == '401')){
// If errors are found initialize all variables to empty so that it protects from future errors
// in other API functions
} else {
let weather = JSON.parse(bodyW) // Get JSON result
weatherText = `It's ${weather.main.temp} degrees in ${weather.name}! ${weatherSort}: ${weatherInfo}`;
headLocationText = `The City of ${basicLocation}`;
}
});
}
// Flickr API
function filckrSearch(){
// Create a new Flickr Client
var flickr = new Flickr(apiKeyFlickr);
// Search Flickr based on latitude and longitude of city
flickr.photos.search({
lat: latLocation,
lon: longLocation,
radius: 20, // Set radius to 20km
sort: flickrsort // Sort the photos by users selection
}).then(function (res) {
var farmid = res.body.photos.photo[0].farm;
}).catch(function (err) {
console.error('bonk', err); // Catch errors
});
}
這是您如何“承諾” weatherSearch
的部分示例。 另一個基本概念相同...將兩個都包含進來將是多余的。
// Main Page
app.post('/', async function (req, res) {
city = req.body.city; // Grab the users input city
//console.log(weatherSort); // Debugging
try {
let { weatherText, headLocationText } = await weatherSearch(); // Openweather API
await filckrSearch(); // <- promisify the same as above
res.render('index', { weather: weatherText, headlocation: headLocationText, lat: latLocation, long: longLocation, imgLinks: imageLinks, WebLinks: websiteLinks, imgLinksFl: imageLinksFlick, restLat: latitudeRest, restLong: longitudeRest, restname: restName, error: null });
} catch (e) {
// do something if you get an error
}
});
// Weather function
function weatherSearch() {
// API URL
let urlw = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKeyWeather}`
// Send out a request
return new Promise((resolve, reject) => {
request(urlw, function (err, response, bodyW) {
// Check for errors
if (err || (JSON.parse(bodyW).cod == '404') || (JSON.parse(bodyW).cod == '401')) {
// If errors are found initialize all variables to empty so that it protects from future errors
// in other API functions
reject(err);
} else {
let weather = JSON.parse(bodyW) // Get JSON result
weatherText = `It's ${weather.main.temp} degrees in ${weather.name}! ${weatherSort}: ${weatherInfo}`;
headLocationText = `The City of ${basicLocation}`;
resolve({ weather, weatherText, headLocationText });
}
});
});
}
基本前提是:
async
/ await
如上,或可以使用.then()
和.catch()
weatherSearch
和flickrSearch
函數都是異步執行的,但方式不同。 weatherSearch
正在發出網絡請求,然后在回調中更新文本全局變量。 flickrSearch
也在發出網絡請求,但正在通過Promise API處理響應。
快速路線代碼的問題在於,它不會編寫為處理您在weatherSearch
和flickrSearch
中調用的異步代碼。 解決此問題的最簡單方法是刪除要在函數中更新的全局變量,並讓它們返回通過網絡請求檢索的值。 這是一個簡單的示例:
// Main Page
app.post('/', async function (req, res) {
const weatherResults = await weatherSearch(); // Here we 'await' the response before rendering the HTML
res.render('index', {
weather: weatherResults.weatherText,
headlocation: weatherResults.headLocationText
});
});
// Weather function
async function weatherSearch() {
let urlw = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKeyWeather}`
return new Promise(function (resolve, reject) {
request(url, function (error, res, body) {
if (err || (JSON.parse(bodyW).cod == '404') || (JSON.parse(bodyW).cod == '401')){
// This is how the Promise API 'returns' an error on failure
reject();
}
else {
let weather = JSON.parse(bodyW)
// This is how the Promise API 'returns' a value on success
resolve({
weatherText: `It's ${weather.main.temp} degrees in ${weather.name}! ${weatherSort}: ${weatherInfo}`,
headLocationText: `The City of ${basicLocation}`
})
}
});
});
}
了解節點中的異步代碼非常重要! 關於Promises,異步等待和回調的文章很多,您可以用來熟悉它。
試試看, BlueBird真的很容易使用,您會在文檔中找到很多示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.