application/json
application/json
or application/x-www.form-urlencoded
nc google.com 80
opens our connection to google.comPOST / HTTP/1.1
creates the request-line, indicating our verb (GET), URI (/), and version (HTTP/1.1)Accept: application/json
myKey=myValue
const http = require('http');
http.createServer(function(request, response) {
if (request.url === '/200') {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('<h1>Hello, world! Status 200 OK!</h1>');
} else if (request.url === '/403') {
response.writeHead(403, { 'Content-Type': 'text/html' });
response.write('<h1>This is Forbidden! Status 403 Forbidden!</h1>');
} else {
response.writeHead(404, { 'Content-Type': 'text/html' });
response.write('<h1>What is that? Status 404 Not Found!</h1>');
}
response.end();
}).listen(8080, function() {
console.log('Listening for requests on port 8080...');
})
Three states of a Promise - Pending - Fulfilled - Rejected
function pause(numberOfSeconds) {
return new Promise((resolve, reject) => {
// resolve is invoked to indicate a success, reject is a failure
// if a value is passed to resolve, it will be caught as the first argument to .then()
// if a value is passed to reject, it will be caught as the first argument to .catch(), or the second argument to .then()
setTimeout(() => resolve(), numberOfSeconds * 1000);
});
}
// Without Promises, we have to nest our code.
// These can get very confusing; this is a simple example, but it's already hard to tell what each setTimeout's delay is connected to.
setTimeout(() => {
console.log(message)
setTimeout(() => {
console.log(message.toUpperCase() + "!")
setTimeout(() => {
console.log(message + "?")
setTimeout(() => {
console.log(message.toLowerCase() + "...")
}, 1 * 1000)
}, 3 * 1000)
}, 2 * 1000)
}, 1 * 1000)
// With Promises, we write more code up front in order for us to have more readable and maintainable code
// We define our promises
function promise1(message, delay) { // "hello"
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message) // "hello"
}, delay * 1000)
})
}
function promise2(message, delay) { // message = "hi"
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message.toUpperCase() + "!") // "HI!"
}, delay * 1000)
})
}
function promise3(message, delay) { // "hey"
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message + "?") // "hey?"
}, delay * 1000)
})
}
function promise4(message, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message.toLowerCase() + "...") // "what's up..."
}, delay * 1000)
})
}
// Then we chain can chain them however we like.
// Returning our strings from our Promises is adding flexibility to our code, allowing us to use the results however we like.
// We replaced the complicated nesting with more modular chaining of .then
promise1("hello", 1)
.then(res1 => {
console.log(res1); // "hello"
return promise2("hi", 2);
})
.then(res2 => {
console.log(res2); // "HI!"
return promise3("hey", 3);
})
.then(res3 => {
console.log(res3); // "hey?"
return promise4("what's up", 1);
})
.then(res4 => {
console.log(res4); // "what's up..."
});
// init is an optional object argument to customize the method (default is 'GET'), headers, or body of the request
// For example, it could take the form:
// const init = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{"title": "Sir", "name": "Robin"}' }
fetch(url, init).then(response => {
// do something with the response
// common first action to take would be parsing the response
// parsing json with response.json(), or text with response.text()
}).then(data => {
// since fetch is returning a promise, we can chain on as many .then calls as we need
})
// Without async/await, we can use .then chains
// We use a .catch method to catch errors
function wrapper() {
promise1("hello", 1)
.then(res1 => {
console.log(res1);
return promise2("hi", 2);
})
.then(res2 => {
console.log(res2);
return promise3("hey", 3);
})
.then(res3 => {
console.log(res3);
return promise4("what's up", 1);
})
.then(res4 => {
console.log(res4);
})
.catch(err => {
console.error("Error encountered:", err)
});;
};
wrapper();
// With async/await, our code looks more like synchronous code
// We use a standard try/catch block to handle errors
// In order for us to use `await` we must be in a function declared with `async`
async function wrapper() {
try {
console.log(await promise1("hello", 1));
console.log(await promise2("hi", 2));
console.log(await promise3("hey", 3));
console.log(await promise4("what's up", 1));
} catch (err) {
console.error("Error encountered:", err)
}
}
wrapper();
- contains metadata for the HTML
- often will include a <title> as well as <link> and <script async> tags
rel
attribute specifies the relation of the link (“stylesheet”, less common may be “icon”, “author”, etc.)href
attribute specifies the URL of the linked file (can be an absolute url or relative path to file in your project)src
attribute specifies the URL of the linked script (if this attribute is present, the