function foo(msg) { return new Promise((resolve, reject) => { setTimeout(() => resolve(msg), 1000) })}
上面函数返回 promise
可以用 then
来获取 resolve
值:
const f = foo('f')f.then(r => console.log(r))
可以用 es6 中的 async await
来替代 promise
:
async function main() { const r = await foo('f') console.log(r)}
onFulfilled returns a promise
var delayMsg = (ms, msg) => new Promise(r => setTimeout(r, ms, msg))Promise.resolve(delayMsg(1000, 'hello')) .then(r => console.log(r)) // log `hello` after 1s
If
onFulfilled
returns a promise, the return value ofthen
will be resolved/rejected by the promise.
promise then chain
foo('ff') .then(r=> console.log(r)) // log ff .then(r => console.log(r)) // log undefined .then(() => 'fff') .then(r => console.log(r)) // log fff .then(() => new Promise(resolve => setTimeout(() => resolve('ffff'), 1000))) .then(r => console.log(r)) // log ffff after 1s
The
then
method returns aPromise
which allows for method chaining.
If the function passed as handler to
then
returns aPromise
, an equivalentPromise
will be exposed to the subsequentthen
in the method chain.
then
的返回值会被下一个 then
捕获, 如果没有 return
默认 return undefined
.
如果返回值是个 Promise
, 下一个 then
会捕获 resolve
的参数.
在 es6 中:
async function bar() { const r = await foo('ff') console.log('-') return r+'~'}function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms))}async function baz() { const r = await bar('gg') console.log('--') await delay(1000) console.log('---') return r+'%'}async function main() { const r = await baz() console.log(r)}
同步执行 task
async function main() { const results = await Promise.all( [task1, task2, task3].map( (task) => task() ) ) console.log(results)}
串行执行 task
function taskSerial() { [task1, task2, task3].reduce( (promise, task) => promise.then(task), Promise.resolve() )}
串行执行并收集结果
function taskSerial(tasks) { return tasks.reduce( (promise, task) => promise.then( r1 => task().then( r2 => r1.concat(r2) // awesome 😄 ) ), Promise.resolve([]) )}
async function taskSerialInES(tasks) { return tasks.reduce( async (promise, task) => { const r1 = await promise const r2 = await task() return r1.concat(r2) }, Promise.resolve([]) )}
测试:
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms))}const task1 = async () => { await delay(1000) console.log('t1 after delay') return 't1'}const task2 = async () => { await delay(3000) console.log('t2 after delay') return 't2'}const task3 = async () => { await delay(100) console.log('t3 after delay') return 't3'}const tasks = [task1, task2, task3]
taskSerial(tasks).then(r => console.log(r))taskSerialInES(tasks).then(r => console.log(r))
for 代替版的串行执行
async function taskSerial(tasks) { for(const task of tasks) { await task() }}
asyncForEach ployfill
async function asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { await callback(array[index], index, array) }}Array.prototype.asyncForEach = async function( asyncTask, allDoneCallback, dealingCallback, failCallback) { try { await asyncForEach( this, async (data, index) => { dealingCallback(data, index); await asyncTask(data, index, this); } ); allDoneCallback(); } catch (error) { failCallback(error); }}
异步递归
// 递归获取文件夹下所有文件及文件夹// return:// [// {// name: 'abc.txt',// path: '/var/abc.txt',// },// {// name: 'def.txt',// path: '/var/def.txt',// },// ]const rgetfiles = async (dir, allFiles = []) => { const isExist = await RNFS.exists(dir) if (!isExist) return allFiles const files = (await RNFS.readDir(dir)).map(f => ({ path: f.path, name: f.name, // size: bytesToSize(f.size), })) allFiles.push(...files) await Promise.all(files.map(async f => (await RNFS.stat(f.path)).isDirectory() && rgetfiles(f.path, allFiles) )) return allFiles}
Catch error
Promise.reject() .then( () => {}, () => console.error('error occurred') // log ) .catch(() => console.log('nothing')) // not called
reject
会被第一个 then
中捕获, 所以最后的 catch
不会执行.
Promise.reject() .then(() => console.log('1')) .then(() => console.log('2')) .then(() => console.log('3')) .catch( ()=>console.log('eee') )
此时第一个 promise
reject
, 被最后的 catch
捕获, 所有中间的 then
都不会执行.
async function
中使用 try catch
捕获异常:
async function main() { try { await mayThrowError() await alsoMayThrowError() } catch (e) { console.log(e) }}