Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce 实现 Promise 串行执行 #22

Open
kangkai124 opened this issue May 14, 2019 · 5 comments
Open

Reduce 实现 Promise 串行执行 #22

kangkai124 opened this issue May 14, 2019 · 5 comments
Labels
JS Solution 解决问题的一些方案

Comments

@kangkai124
Copy link
Owner

kangkai124 commented May 14, 2019

function runPromiseByQueue (myPromises) {
  myPromises.reduce(
    (previousPromise, nextPromise) => previousPromise.then(() => nextPromise()),
    Promise.resolve()
  )
}

上一个 Promise 执行,完毕后调用下一个 Promise,并作为一个新的 Promise 返回,下次迭代继续这个循环。

const createPromise = (time, id) => () =>
	new Promise(resolve => 
    setTimeout(() => {
    	console.log("promise", id)
      resolve()
    }, time)
  )

runPromiseByQueue([
  createPromise(3000, 1),
  createPromise(2000, 2),
  createPromise(1000, 3),
])

// loading 3000 ms
// promise 1
// loading 2000 ms
// promise 2
// loading 1000 ms
// promise 3

Reduce 的作用是在内存中生成这个队列,而不需要把这个冗余的队列写在代码里。

@kangkai124
Copy link
Owner Author

在 async/await 的支持下,runPromiseByQueue 函数可以更为简化:

async function runPromiseByQueue(myPromises) {
  for (let func of myPromises) {
    await func();
  }
}

@kangkai124
Copy link
Owner Author

@kangkai124
Copy link
Owner Author

更多 Promise 扩展:promise-fun

@kangkai124 kangkai124 added JS Solution 解决问题的一些方案 labels May 14, 2019
@kangkai124
Copy link
Owner Author

kangkai124 commented May 15, 2019

Reduce Polyfill

Array.prototype.reduce2 = function(callback /*, initialValue*/) {
  if (this === null) {
    throw new TypeError('Array.prototype.reduce called on null or undefined');
  }
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  
  var thisArr = Object(this),       // thisArr 调用该方法的数组
      len = thisArr.length >>> 0,   // 数组的长度,`x >>> 0` 保证 x 为正整数
      index = 0,                    // index 下标             
      value;                        // 每次传入累加器的值

  // 如果参数长度大于等于二,说明传入了初始值,
  // 去拿下标为 1 的值作为初始值    
  if (arguments.length >= 2) {
    value = arguments[1];
  } else {
    // 判断数组里的空位,将数组里的第一个非falsy值初始化为初始值 value
    while (index < len && !(index in thisArr)) {
      index++;
    }
    // 此时传入的参数长度小于等于1,如果 len 也是0,报错,因为没有初始值
    if (index >= len) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    // 此时将数组第一项的值赋值给 value,然后下标++
    value = thisArr[index++];
  }

  // 队列开始
  while (index < len) {
    if (index in thisArr) {
      value = callback(value, thisArr[index], index, thisArr);
    }

    index++;
  }
  // 更新 value
  return value;
}

@kangkai124
Copy link
Owner Author

var len = arr.length >>> 0 是个什么鬼

>> 是有符号右移
该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位(即符号位)以填充左侧。

9 >> 2 得到 2:

9 (base 10): 00000000000000000000000000001001 (base 2)
                  --------------------------------
9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)

-9 >> 2 得到 -3,因为符号被保留了。

-9 (base 10): 11111111111111111111111111110111 (base 2)
                   --------------------------------
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)

>>> 是无符号右移
该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(即便右移 0 个比特,结果也是非负的。

对于非负数,有符号右移和无符号右移总是返回相同的结果。

但是对于负数,由于右移后左侧总是补0,所以总是得到非负数。

-9 (base 10): 11111111111111111111111111110111 (base 2)
                    --------------------------------
-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)

知道了 >>> 是无符号右移,但是右移 0 有什么意义呢??

答案就是:

It doesn't just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.

所以,移位操作符做了两件事情,第一将不是 number 的数据转为 number,第二就是将 number 转为无符号的 32bit 数据, 也就是 Uint32 类型。

所以,最上面的代码的意义就是,保证 len 是数字类型,且为正整数,在无意义的情况下取值为0。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JS Solution 解决问题的一些方案
Projects
None yet
Development

No branches or pull requests

1 participant