# 异步编程

Promise 是 JavaScript 中用于处理异步操作的核心对象，有效避免了传统回调函数的嵌套问题。

```javascript
let flag = true;
const promise = new Promise((resolve, reject) => {
    flag ? resolve('Successful.') : reject('Unsuccessful.');
});
promise.then(
    data => console.log(data),
    error => console.error(error)
);
```

执行下面的代码，通过异步编程串行执行多个操作。

```javascript
const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
        console.log('Successful #1.');
        resolve(['foo']);
    }, 1000);
});
promise
	.then(data => {
		return new Promise((resolve, reject) => {
			setTimeout(() => {
                console.log('Successful #2.');
                data.push('bar');
                resolve(data);
            }, 1000);
        });
	})
    .then(data => {
		return new Promise((resolve, reject) => {
			setTimeout(() => {
                console.log('Successful #3.');
                data.push('baz');
                resolve(data);
            }, 1000);
        });
	})
    .then(data => {
		console.log(data);
});
console.log('Hello World!');
```

执行下面的代码，捕获异步编程中的失败信息。

```javascript
const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		reject('Unsuccessful.');
    }, 1000);
});
promise.catch(error => {
	console.error(error);
});
```

执行下面的代码，模拟异步编程串行执行多个 HTTP 请求。

```javascript
let result = [];
fetch('https://api.example.com/users')
    .then(response => {
    	if (!response.ok) {
            throw new Error('Unsuccessful #1.');
        }
    	return response.json();
	})
    .then(data => {
    	console.log('Successful #1.');
    	result.push(data);
    	return fetch('https://api.example.com/orders');
	})
    .then(response => {
    	if (!response.ok) {
			throw new Error('Unsuccessful #2.');
        }
    	return response.json();
	})
    .then(data => {
    	console.log('Successful #2.');
    	result.push(data);
    	return fetch('https://api.example.com/goods');
	})
    .then(response => {
    	if (!response.ok) {
            throw new Error('Unsuccessful #3.');
        }
    	return response.json();
	})
    .then(data => {
    	console.log('Successful #3.');
    	result.push(data);
	})
    .catch(error => console.error(error))
    .finally(() => console.log(result));
console.log('Hello World!');
```

执行下面的代码，模拟异步编程并行执行多个 HTTP 请求。

```javascript
const urls = [
    'https://api.example.com/users',
    'https://api.example.com/orders',
    'https://api.example.com/goods'
];
Promise.all(urls.map(url => fetch(url)))
    .then(responses => {
    	return Promise.all(
            responses.map((response, index) => {
                if (!response.ok) {
                    throw new Error(`Unsuccessful #${index + 1}.`);
                }
                return response.json();
            })
        );
	})
    .then(data => console.log(data))
    .catch(error => console.error(error));
console.log('Hello World!');
```

执行下面的代码，通过函数的方式模拟异步编程串行执行多个操作。

```javascript
function func1() {
	fetch('https://api.example.com/users')
		.then((response) => {
        	if (!response.ok) {
                throw new Error('Unsuccessful #1.');
            }
        	return response.json();
    })
        .then((data) => console.log(data));
    	.catch(error => console.error(error));
}

function func2() {
	fetch('https://api.example.com/orders')
		.then((response) => {
        	if (!response.ok) {
                throw new Error('Unsuccessful #2.');
            }
        	return response.json();
    })
        .then((data) => console.log(data));
    	.catch(error => console.error(error));
}

function func3() {
	fetch('https://api.example.com/goods')
		.then((response) => {
        	if (!response.ok) {
                throw new Error('Unsuccessful #3.');
            }
        	return response.json();
    })
        .then((data) => console.log(data));
    	.catch(error => console.error(error));
}

async function main() {
    await func1();
    await func2();
    await func3();
}
main();
```

执行下面的代码，通过函数的方式模拟异步编程并行执行多个操作。

```javascript
function func1() {
	fetch('https://api.example.com/users')
		.then((response) => {
        	if (!response.ok) {
                throw new Error('Unsuccessful #1.');
            }
        	return response.json();
    })
        .then((data) => console.log(data));
    	.catch(error => console.error(error));
}

function func2() {
	fetch('https://api.example.com/orders')
		.then((response) => {
        	if (!response.ok) {
                throw new Error('Unsuccessful #2.');
            }
        	return response.json();
    })
        .then((data) => console.log(data));
    	.catch(error => console.error(error));
}

function func3() {
	fetch('https://api.example.com/goods')
		.then((response) => {
        	if (!response.ok) {
                throw new Error('Unsuccessful #3.');
            }
        	return response.json();
    })
        .then((data) => console.log(data));
    	.catch(error => console.error(error));
}

async function main() {
    await Promise.all([func1(), func2(), func3()]);
}
main();
```

